BZOJ 1036:树的统计Count(树链剖分)
http://www.lydsy.com/JudgeOnline/problem.php?id=1036
题意:中文题意。
思路:也是普通的树链剖分。唯一注意的点是在change函数中
1 while(top[u] != top[v]) { 2 if(dep[top[u]] < dep[top[v]]) swap(u, v); 3 if(type == 1) ans = max(ans, query(1, 1, tim, tid[top[u]], tid[u], type)); 4 else ans += query(1, 1, tim, tid[top[u]], tid[u], type); 5 u = fa[top[u]]; 6 }
这里的dep比较的是节点的top节点的深度,而不是直接比较节点的深度。因为这里WA了好久。只能说还未完全理解透细节。
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <queue> 8 #include <vector> 9 using namespace std; 10 #define N 30010 11 #define INF 10000000000 12 #define lson rt<<1, l, m 13 #define rson rt<<1|1, m + 1, r 14 15 struct node 16 { 17 int v, nxt, w; 18 }edge[N*2]; 19 int top[N], tid[N], fa[N], son[N], siz[N], dep[N], rak[N], w[N], tim; 20 int head[N], tot; 21 struct T 22 { 23 long long sum; 24 long long ma; 25 }tree[N<<2]; 26 27 void init() 28 { 29 memset(head, -1, sizeof(head)); 30 memset(son, -1, sizeof(son)); 31 tot = tim = 0; 32 } 33 34 void add(int u, int v) 35 { 36 edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++; 37 } 38 39 void dfs1(int u, int f, int d) 40 { 41 siz[u] = 1; 42 dep[u] = d; 43 fa[u] = f; 44 for(int i = head[u]; ~i; i = edge[i].nxt) { 45 int v = edge[i].v; 46 if(v == f) continue; 47 dfs1(v, u, d + 1); 48 siz[u] += siz[v]; 49 if(son[u] == -1 || siz[son[u]] < siz[v]) son[u] = v; 50 } 51 } 52 53 void dfs2(int u, int tp) 54 { 55 top[u] = tp; 56 tid[u] = ++tim; 57 rak[tim] = u; 58 if(son[u] == -1) return ; 59 dfs2(son[u], tp); 60 for(int i = head[u]; ~i; i = edge[i].nxt) { 61 int v = edge[i].v; 62 if(v != fa[u] && v != son[u]) dfs2(v, v); 63 } 64 } 65 66 void pushup(int rt) 67 { 68 tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum; 69 tree[rt].ma = max(tree[rt<<1].ma, tree[rt<<1|1].ma); 70 } 71 72 void build(int rt, int l, int r) 73 { 74 tree[rt].sum = 0; 75 tree[rt].ma = 0; 76 if(l == r) { 77 tree[rt].sum = w[rak[l]]; 78 tree[rt].ma = w[rak[l]]; 79 return ; 80 } 81 int m = (l + r) >> 1; 82 build(lson); build(rson); 83 pushup(rt); 84 } 85 86 void update(int rt, int l, int r, int id, int val) 87 { 88 if(l == r && l == id) { 89 tree[rt].sum = val; 90 tree[rt].ma = val; 91 return ; 92 } 93 int m = (l + r) >> 1; 94 if(id <= m) update(lson, id, val); 95 else update(rson, id, val); 96 pushup(rt); 97 } 98 99 long long query(int rt, int l, int r, int L, int R, int type) 100 { 101 long long ans = 0; 102 if(type == 1) ans = -INF; 103 if(L <= l && r <= R) { 104 if(type == 1) ans = max(ans, tree[rt].ma); 105 else ans += tree[rt].sum; 106 return ans; 107 } 108 int m = (l + r) >> 1; 109 if(L <= m) { 110 if(type == 1) ans = max(ans, query(lson, L, R, type)); 111 else ans += query(lson, L, R, type); 112 } 113 if(m < R) { 114 if(type == 1) ans = max(ans, query(rson, L, R, type)); 115 else ans += query(rson, L, R, type); 116 } 117 return ans; 118 } 119 120 long long change(int u, int v, int type) 121 { 122 long long ans = 0; 123 if(type == 1) ans = -INF; 124 while(top[u] != top[v]) { 125 if(dep[top[u]] < dep[top[v]]) swap(u, v); 126 if(type == 1) ans = max(ans, query(1, 1, tim, tid[top[u]], tid[u], type)); 127 else ans += query(1, 1, tim, tid[top[u]], tid[u], type); 128 u = fa[top[u]]; 129 } 130 if(dep[u] > dep[v]) swap(u, v); 131 if(type == 1) ans = max(ans, query(1, 1, tim, tid[u], tid[v], type)); 132 else ans += query(1, 1, tim, tid[u], tid[v], type); 133 return ans; 134 } 135 136 int main() 137 { 138 int n, q; 139 scanf("%d", &n); 140 init(); 141 for(int i = 1; i < n; i++) { 142 int u, v; 143 scanf("%d%d", &u, &v); 144 add(u, v); add(v, u); 145 } 146 for(int i = 1; i <= n; i++) scanf("%d", &w[i]); 147 dfs1(1, 1, 1); 148 dfs2(1, 1); 149 build(1, 1, tim); 150 // for(int i = 1; i <= n; i++) printf("tid[%d] : %d\n", i, tid[i]); 151 scanf("%d", &q); 152 while(q--) { 153 char s[10]; 154 int a, b; 155 scanf("%s%d%d", s, &a, &b); 156 if(s[0] == 'C') { 157 update(1, 1, tim, tid[a], b); 158 } else { 159 int type = 1; 160 if(s[1] == 'S') type = 2; 161 printf("%lld\n", change(a, b, type)); 162 } 163 } 164 return 0; 165 }