BZOJ1103: [POI2007]大都市meg
题解
应该是个dfs序裸题
土路修成公路时, 把节点子树的权值全部 -1.
查询直接前缀和。
树状数组维护
代码
1 #include<cstring> 2 #include<iostream> 3 #include<cstdio> 4 #include<algorithm> 5 #define rd read() 6 using namespace std; 7 8 const int N = 5e5; 9 10 int f[N], head[N], tot, size[N], cnt, id[N]; 11 int sum[N], n, m; 12 13 struct edge { 14 int nxt, to; 15 }e[N << 1]; 16 17 int read() { 18 int X = 0, p = 1; char c = getchar(); 19 for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1; 20 for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0'; 21 return X * p; 22 } 23 24 void added(int u, int v) { 25 e[++tot].to = v; 26 e[tot].nxt = head[u]; 27 head[u] = tot; 28 } 29 30 void add(int u, int v) { 31 added(u, v); added(v, u); 32 } 33 34 void dfs(int u) { 35 size[u] = 1; 36 id[u] = ++cnt; 37 for(int i = head[u]; i; i = e[i].nxt) { 38 int nt = e[i].to; 39 if(nt == f[u]) continue; 40 f[nt] = u; 41 dfs(nt); 42 size[u] += size[nt]; 43 } 44 } 45 46 inline int lowbit(int x) { 47 return x & (-x); 48 } 49 50 inline void modify(int x, int d) { 51 for(; x <= n * 2; x += lowbit(x)) sum[x] += d; 52 } 53 54 inline int query(int x) { 55 int re = 0; 56 for(; x; x -= lowbit(x)) re += sum[x]; 57 return re; 58 } 59 60 int main() 61 { 62 n = rd; 63 for(int i = 1; i < n; ++i) { 64 int x = rd, y = rd; 65 add(x, y); 66 } 67 dfs(1); 68 for(int i = 2; i <= n; ++i) { 69 modify(id[i], 1); 70 modify(id[i] + size[i], -1); 71 } 72 m = rd; 73 for(int i = 1; i <= n + m - 1; ++i) { 74 char k[2]; scanf("%s", k); 75 if(k[0] == 'W') { 76 int x = rd; 77 int ans = query(id[x]); 78 printf("%d\n", ans); 79 } 80 else { 81 int x = rd, y = rd; 82 if(f[y] == x) swap(x, y); 83 modify(id[x], -1); 84 modify(id[x] + size[x], 1); 85 } 86 } 87 }