[Luogu] trip
https://www.luogu.org/problemnew/show/T28848#sub
#include <iostream> #include <cstdio> using namespace std; const int N = 1e5 + 10; int top[N], fa[N], deep[N], size[N], son[N], tree[N], bef[N]; int head[N], W[N << 2], F[N << 2], Size[N << 2]; int n, Ty, tim, now = 1; struct Node{int v, nxt;} G[N << 1]; int Answer; #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } inline void Add(int u, int v) {G[now].v = v; G[now].nxt = head[u]; head[u] = now ++;} void Dfs_1(int u, int dep, int f_) { deep[u] = dep; fa[u] = f_; size[u] = 1; for(int i = head[u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(v != f_) { Dfs_1(v, dep + 1, u); size[u] += size[v]; if(size[v] > size[son[u]]) son[u] = v; } } } void Dfs_2(int u, int tp) { top[u] = tp; tree[u] = ++ tim; if(!son[u]) return ; Dfs_2(son[u], tp); for(int i = head[u]; ~ i; i = G[i].nxt) { int v = G[i].v; if(v != fa[u] && v != son[u]) Dfs_2(v, v); } } #define lson jd << 1 #define rson jd << 1 | 1 void Build_tree(int l, int r, int jd) { Size[jd] = r - l + 1; if(l == r) { W[jd] = 1; return ; } int mid = (l + r) >> 1; Build_tree(l, mid, lson); Build_tree(mid + 1, r, rson); W[jd] = W[lson] + W[rson]; } void Down(int jd) { int f = F[jd]; W[lson] += Size[lson] * f; W[rson] += Size[rson] * f; F[lson] += f; F[rson] += f; F[jd] = 0; } void Sec_G(int l, int r, int jd, int x, int y, int yj) { if(x <= l && r <= y) {W[jd] += (r - l + 1) * yj; F[jd] += yj; return ;} if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y, yj); if(y > mid) Sec_G(mid + 1, r, rson, x, y, yj); W[jd] = W[lson] + W[rson]; } inline void Sec_G_imp(int x, int y) { int tp1 = top[x], tp2 = top[y]; while(tp1 != tp2) { if(deep[tp1] < deep[tp2]) swap(x, y), swap(tp1, tp2); Sec_G(1, n, 1, tree[tp1], tree[x], -1); x = fa[tp1]; tp1 = top[x]; } if(x == y) return ; if(deep[x] < deep[y]) swap(x, y); Sec_G(1, n, 1, tree[y] + 1, tree[x], -1); } void Sec_A(int l, int r, int jd, int x, int y) { if(x <= l && r <= y) { Answer += W[jd]; return ; } if(F[jd]) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_A(l, mid, lson, x, y); if(y > mid) Sec_A(mid + 1, r, rson, x, y); } inline int Sec_A_imp(int x) { int tp1 = top[x], ret = 0; while(tp1 != 1) { Answer = 0; Sec_A(1, n, 1, tree[tp1], tree[x]); ret += Answer; x = fa[tp1]; tp1 = top[x]; } if(x == 1) return ret; Answer = 0; Sec_A(1, n, 1, tree[1] + 1, tree[x]); ret += Answer; return ret; } int main() { n = read(); for(int i = 1; i <= n; i ++) head[i] = -1; for(int i = 1; i < n; i ++) { int u = read(), v = read(); Add(u, v); Add(v, u); } Dfs_1(1, 1, 0); Dfs_2(1, 1); Build_tree(1, n, 1); Ty = read(); Ty = Ty + n - 1; while(Ty --) { string opt; cin >> opt; if(opt[0] == 'A') { int x = read(), y = read(); Sec_G_imp(x, y); } else { int x = read(); cout << Sec_A_imp(x) << "\n"; } } return 0; } /* 5 1 2 1 3 1 4 4 5 4 W 5 A 1 4 W 5 A 4 5 W 5 W 2 A 1 2 A 1 3 */