[Bzoj 3531] [Sdoi 2014] Travel
Dynamic Open point segment tree + Tree profile.
After writing the compilation once over the sample handed 1A this feeling is quite cool qaq.
#include <bits/stdc++.h> #define MAXN 100010using namespace Std;int N, q;int W[maxn], c[maxn];//------------------ -------------------------------------------------//struct Edge{int to, next;} EDGE[MAXN << 1];int H[MAXN], cnt;void Add (int u, int v) {cnt ++;edge[cnt].to = V;edge[cnt].next = H[u];h[u] = cnt;} -------------------------------------------------------------------//int SON[MAXN], TOP[MAXN], POS[MAXN], Dfs_ Clock, Size[maxn];int FA[MAXN], dep[maxn];void dfs1 (int u) {dep[u] = Dep[fa[u]] + 1;size[u] = 1;for (int i = h[u]; i; i = ed Ge[i].next) {int v = edge[i].to;if (v = = Fa[u]) continue;fa[v] = U;DFS1 (v); Size[u] + = size[v];if (Size[v] > Size[son[u]]) Son[u] = V;}} void dfs2 (int u, int tp) {Pos[u] = + + Dfs_clock;top[u] = tp;if (Son[u]) DFS2 (Son[u], TP); for (int i = h[u]; i; i = Edge[i].nex t) {int v = edge[i].to;if (v = = Fa[u] | | v = = son[u]) continue;dfs2 (V, v);}} -------------------------------------------------------------------//#define M 10000010int ROOT[MAXN], lc[m], RC[M], mx[m], s[m], smz;void pushup (int id) {S[id] = S[lc[id]] + s[rc[id]];mx[id] = max (Mx[lc[id], Mx[rc[id]]);} void Update (int &id, int l, int r, int p, int val) {if (id = = 0) id = + + smz;if (L = = r) {S[id] = val, mx[id] = Val;return; }int mid = L + R >> 1;if (P <= mid) Update (Lc[id], L, Mid, P, Val), Else Update (Rc[id], mid+1, R, p, Val);p ushup (ID) ;} int asksum (int id, int l, int r, int l, int r) {if (id = = 0) return 0;if (L = = L && r = = r) Return S[id];int mid = L + R >> 1;if (r <= Mid) return Asksum (Lc[id], L, Mid, L, R), if (L > Mid) return Asksum (Rc[id], mid+1, R, L, R); retur N Asksum (Lc[id], L, Mid, L, mid) + asksum (Rc[id], mid+1, R, Mid+1, r);} int askmx (int id, int l, int r, int l, int r) {if (id = = 0) return 0;if (L = = L && r = = r) Return Mx[id];int mid = L + R >> 1;if (r <= Mid) return ASKMX (Lc[id], L, Mid, L, R), if (L > Mid) return askmx (Rc[id], mid+1, R, L, R); return Max (ASKMX (Lc[id], L, Mid, L, mid), ASKMX (Rc[id], mid+1, R, Mid+1, R));} int asksum (int u, int v) {int C = C[u], ret = 0;while (top[u]! = Top[v]) {if (Dep[top[u]] < DEP[TOP[V]]) swap (U, v); ret + = Asksum (root [C], 1, N, Pos[top[u]], pos[u]); u = Fa[top[u]];} if (Dep[u] > Dep[v]) Swap (U, v), ret + = Asksum (Root[c], 1, N, Pos[u], pos[v]); return ret;} int askmx (int u, int v) {int C = C[u], ret = 0;while (top[u]! = Top[v]) {if (Dep[top[u]] < DEP[TOP[V]]) swap (U, v); r ET = max (ret, ASKMX (Root[c], 1, N, Pos[top[u]], pos[u])); u = Fa[top[u]];} if (Dep[u] > Dep[v]) Swap (U, v), ret = max (ret, ASKMX (Root[c], 1, N, Pos[u], pos[v])); return ret;} int main () {char cmd[2];scanf ("%d%d", &n, &q), for (int i = 1; I <= n; i + +) scanf ("%d%d", &w[i], &c[i] int x, y;for (int i = 1; i < n; i + +) {scanf ("%d%d", &x, &y), add (x, y), add (y, x);} DFS1 (1);d FS2 (1, 1), for (int i = 1; I <= n; i + +) update (Root[c[i]], 1, N, Pos[i], w[i]), while (Q-) {scanf ("%s", cmd); scan F ("%d%d", &x, &y), switch (cmd[1]) {case ' C ': Update (Root[c[x]], 1, N, Pos[x], 0), c[x] = Y Update (Root[y], 1, N, Pos[x], w[x]); Break;case ' W ': Update (Root[c[x]], 1, N, Pos[x], w[x] = y); Break;case ' S ':p rintf ("%d\n" , Asksum (x, y)), break;case ' M ': printf ("%d\n", askmx (x, y)); return 0;}
[Tree chain split]