Title Link: http://poj.org/problem?id=2763
Test instructions: Give a number, the edge between the right value, and then two operations, the first: the weight of any two points and, second, modify the weight of two points on the tree.
Puzzle: Simple tree-chain split.
#include <iostream> #include <cstdio> #include <cstring>using namespace std;const int M = 1e5 + 10;struct Edge {int V, next;} Edge[m << 1];int head[m], e;int top[m];int fa[m];int num[m];int p[m];int fp[m];int deep[m];int son[M];int pos;void Init () {memset (head,-1, sizeof (head)); Memset (son,-1, sizeof (son)); e = 0; pos = 1;} void Add (int u, int v) {edge[e].v = v; Edge[e].next = Head[u]; Head[u] = e++;} void dfs1 (int u, int pre, int d) {deep[u] = D; Fa[u] = pre; Num[u] = 1; for (int i = head[u]; i =-1; i = edge[i].next) {int v = EDGE[I].V; if (v! = Pre) {dfs1 (V, u, D + 1); Num[u] + = Num[v]; if (son[u] = = 1 | | num[son[u]] < Num[v]) {Son[u] = V; }}}}void GetPos (int u, int sp) {top[u] = SP; P[u] = pos++; Fp[p[u]] = u; if (son[u] = =-1) return; GetPos (Son[u], SP); for (int i = head[u]; I! =-1; i = EDGE[I].NEXT) {int v = EDGE[I].V; if (v = son[u] && v! = Fa[u]) {GetPos (V, v); }}}struct TnT {int L, r, sum;} T[m << 2];int ed[m][3];void pushup (int i) {t[i].sum = t[i << 1].sum + t[(i << 1) | 1].sum;} void build (int l, int r, int i) {int mid = (L + r) >> 1; T[I].L = L, T[I].R = r, t[i].sum = 0; if (L = = r) {return; } build (L, Mid, I << 1); Build (mid + 1, R, (i << 1) | 1); Pushup (i);} void Updata (int pos, int i, int ad) {int mid = (t[i].l + t[i].r) >> 1; if (t[i].l = = T[I].R && T[I].L = = pos) {t[i].sum = AD; return; } if (Mid < POS) {Updata (pos, (i << 1) | 1, AD); } else {Updata (pos, I << 1, AD); } pushup (i);} int query (int l, int r, int i) {int mid = (t[i].l + t[i].r) >> 1; if (T[I].L = = L && T[I].R = = r) {return t[i].sum; } pushup (i); if (mid < L) {return query (L, R, (i << 1) | 1); } else if (Mid >= R) {return query (L, R, I << 1); } else {return query (L, Mid, I << 1) + query (mid + 1, R, (i << 1) | 1); }}int find (int u, int v) {int f1 = Top[u], F2 = top[v]; int tmp = 0; while (f1! = F2) {if (Deep[f1] < DEEP[F2]) {swap (f1, F2); Swap (U, v); } tmp + = query (P[f1], p[u], 1); U = fa[f1], f1 = Top[u]; } if (U = = v) return tmp; if (Deep[u] > Deep[v]) Swap (U, v); return tmp + query (P[son[u]], p[v], 1);} int main () {int n, q, S, CP, U, v; scanf ("%d%d%d", &n, &q, &s); Init (); for (int i = 0; i < n-1; i++) {for (int j = 0; J < 3; J + +) {scanf ("%d", &ed[i][j]); } Add (Ed[i][0], ed[i][1]); Add (Ed[i][1], ed[i][0]); } dfs1 (1, 0, 0); GetPos (1, 1); Build (0, POS, 1); for (int i= 0; i < n-1; i++) {if (deep[ed[i][0]] > deep[ed[i][1]) {swap (ed[i][0], ed[i][1]); } updata (P[ed[i][1]], 1, ed[i][2]); } while (q--) {scanf ("%d", &CP); if (cp = = 0) {scanf ("%d", &u); printf ("%d\n", find (S, u)); s = u; } else {scanf ("%d%d", &u, &v); Updata (P[ed[u-1][1]], 1, v); }} return 0;}
Poj 2763 Housewife Wind (tree-chain split + single-point query + interval modification)