Source: POJ 2763 housewife Wind
Test instructions: Give you a tree 2 operations 0 x the shortest path to the current point to X and then the current position is x; 1 I x Place the weight of the I edge at x
Idea: Tree two point u, v distance is D[u]+d[v]-2*d[lca (u,v)] Now the D array is the change corresponding to each side of the change he modifies an interval with a timestamp to process each point of the area and then modifies the leaf node of the segment tree with the segment tree the distance from the root to each point To find the nearest common ancestor, just fall. Maintain d arrays with line segment trees
All kinds of mistakes, 4 hours, no harm.
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int maxn = 200010; struct Edge{int u, V, W, next;} EDGES[MAXN*2], E[maxn];int e[maxn*2], h[maxn*2], i[maxn*2], L[MAXN], r[maxn];int dp[maxn*2][40];int cnt, clock, Dfn;int F Irst[maxn];int a[maxn<<2];int b[maxn];int add[maxn<<2];int degree[maxn];int vis[maxn];void AddEdge (int u, int V, int w) {edges[cnt].u = U;EDGES[CNT].V = V;EDGES[CNT].W = W;edges[cnt].next = First[u];first[u] = cnt++;edges[cnt].u = V;EDGES[CNT].V = U;EDGES[CNT].W = W;edges[cnt].next = First[v];first[v] = cnt++;} void Dfs (int u, int fa, int dep) {E[++clock] = u; H[clock] = dep;i[u] = clock; L[u] = ++DFN;B[DFN] = u;for (int i = first[u]; I! = 1; i = edges[i].next) {int v = edges[i].v;if (v = = FA) continue;if (Vis[v] ) Continue;vis[v] = True;dfs (V, U, dep+1); E[++clock] = u; H[clock] = dep;} R[u] = DFN;} void Rmq_init (int n) {for (int i = 1; I <= n; i++) dp[i][0] = i;for (int j = 1; (1<<j) <= N; J + +) for (int i = 1; i+ (1<<J)-1 <= N; i++) {if (H[dp[i][j-1]] < h[dp[i+ (1<< (j-1))][j-1]]) dp[i][j] = dp[i][j-1];elsedp[i][j] = dp[i+ (1<< (j-1)) ][J-1];}} int RMQ (int l, int r) {L = I[l], r = i[r];if (L > R) Swap (L, r); int len = r-l+1, k = 0;while ((1<<k) <= len) k++;k- -;if (H[dp[l][k]] < h[dp[r-(1<<k) +1][k]] return E[dp[l][k]];elsereturn e[dp[r-(1<<k) +1][k]];} void Pushdown (int rt, int l, int r) {int k = (r-l+1), if (Add[rt]) {a[rt<<1] + = add[rt]* (k (k>>1)); a[rt<<1| 1] + = add[rt]* (k>>1); add[rt<<1] + add[rt];add[rt<<1|1] + = Add[rt];add[rt] = 0;}} void build (int l, int r, int rt) {A[rt] = 0;add[rt] = 0;if (L = = r) Return;int m = (L + R) >> 1;build (L, M, rt<<1 ); Build (M+1, R, rt<<1|1);} void update (int x, int y, int l, int r, int rt, int num) {if (L = = x && r = = y) {A[rt] + = (r-l+1) *num;add[rt] + = num; return;} Pushdown (RT, L, R), int m = (L + R) >> 1;if (y <= m) update (x, Y, L, M, rt<<1, num), else if (x > M) update (x, Y, m+1, R, Rt<<1|1, num), Else{update (X, M, L, M, rt<<1, num); update (m+1, Y, m+1, R, Rt<<1|1, num);} A[RT] = a[rt<<1] + a[rt<<1|1];} int query (int x, int l, int r, int rt) {if (L = = r) {return A[RT];} Pushdown (RT, L, R); int m = (L + R) >> 1;int ans = 0;if (x <= m) ans = query (x, L, M, rt<<1); Elseans = Query (x , M+1, R, Rt<<1|1); A[rt] = a[rt<<1] + a[rt<<1|1];return ans;} int main () {int cas = 1;int t;//scanf ("%d", &t); int S, to, Root, N, Q;while (scanf ("%d%d", &n, &q, &s)! = EOF) {memset (Vis, 0, sizeof (VIS)), memset (first,-1, sizeof (first)), memset (degree, 0, sizeof (degree)); clock = cnt = DFN = 0;build (1, N, 1),//for (int i = 1; I <= n; i++)//scanf ("%d", &b[i]), for (int i = 1; i < n; i++) {int u, V, w;scanf ( "%d%d%d", &u, &v, &w); e[i].u = U;E[I].V = V;E[I].W = W; Addedge (U, V, 0);d egree[v]++;} for (int i = 1; I <= n; i++) if (!degree[i]) {Vis[i] = True;dfs (i,-1, 0); root = I;break;} Rmq_init (2*n-1);//puTS ("1"); for (int i = 1; i < n; i++) {int u = e[i].u;int v = e[i].v;int w = e[i].w;//printf ("***%d%d\n", L[v], r[v]); if (L [u] < l[v]) update (L[V], r[v], 1, N, 1, W), Elseupdate (L[u], r[u], 1, N, 1, w);} while (q--) {int x;scanf ("%d", &x), if (!x) {scanf ("%d", &to), int d1 = query (L[s], 1, N, 1), int d2 = query (L[to], 1, N, 1); int LCA = RMQ (S, to); int d3 = query (L[lca], 1, N, 1)//printf ("***%d%d%d\n", D1, D2, D3);p rintf ("%d\n", d1+d2-2*d3); printf ("%d\n", DFN); s = to;} Else{int I, w;scanf ("%d%d", &i, &w); int x = W-E[I].W;E[I].W = W;int v = e[i].v;int u = e[i].u;if (L[u] < L[v] ) Update (L[v], r[v], 1, N, 1, x), Elseupdate (L[u], r[u], 1, N, 1, x);}}} return 0;}