[ZJOI2008]树的统计
作者:互联网
一看就知道,一道树链剖分板子题,原来2008年的ZJOI这么可爱。
那啥别忘了权值有负数,所以查询最大值的时候ans初始值应该是-INF,别写成0了。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps =1e-8; 19 const int maxn = 3e4 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) putchar('-'), x = -x; 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 int n, w[maxn]; 37 vector<int> v[maxn]; 38 39 bool vis[maxn]; 40 int fa[maxn], deep[maxn], size[maxn], maxson[maxn]; 41 void dfs1(int now) 42 { 43 size[now] = vis[now] = 1; 44 for(int i = 0; i < (int)v[now].size(); ++i) 45 { 46 if(!vis[v[now][i]]) 47 { 48 fa[v[now][i]] = now; 49 deep[v[now][i]] = deep[now] + 1; 50 dfs1(v[now][i]); 51 size[now] += size[v[now][i]]; 52 if(!maxson[now] || size[v[now][i]] > size[maxson[now]]) maxson[now] = v[now][i]; 53 } 54 } 55 } 56 int top[maxn], dfsx[maxn], pos[maxn], cnt = 0; 57 void dfs2(int now) 58 { 59 vis[now] = 1; 60 dfsx[now] = ++cnt; pos[cnt] = now; 61 if(maxson[now]) 62 { 63 top[maxson[now]] = top[now]; 64 dfs2(maxson[now]); 65 } 66 for(int i = 0; i < (int)v[now].size(); ++i) 67 { 68 if(!vis[v[now][i]] && v[now][i] != maxson[now]) 69 { 70 top[v[now][i]] = v[now][i]; 71 dfs2(v[now][i]); 72 } 73 } 74 } 75 76 int l[maxn << 2], r[maxn << 2]; 77 ll Max[maxn << 2], sum[maxn << 2]; 78 void pushup(int now) 79 { 80 sum[now] = sum[now << 1] + sum[now << 1 | 1]; 81 Max[now] = max(Max[now << 1], Max[now << 1 | 1]); 82 } 83 void build(int L, int R, int now) 84 { 85 l[now] = L; r[now] = R; 86 if(L == R) {sum[now] = Max[now] = w[pos[L]]; return;} 87 int mid = (L + R) >> 1; 88 build(L, mid, now << 1); 89 build(mid + 1, R, now << 1 | 1); 90 pushup(now); 91 } 92 void update(int id, int d, int now) 93 { 94 if(l[now] == r[now]) {sum[now] = Max[now] = d; return;} 95 int mid = (l[now] + r[now]) >> 1; 96 if(id <= mid) update(id, d, now << 1); 97 else update(id, d, now << 1 | 1); 98 pushup(now); 99 } 100 ll query(int L, int R, int now, int flag) 101 { 102 if(l[now] == L && r[now] == R) return flag ? sum[now] : Max[now]; 103 int mid = (l[now] + r[now]) >> 1; 104 if(R <= mid) return query(L, R, now << 1, flag); 105 else if(L > mid) return query(L, R, now << 1 | 1, flag); 106 else 107 { 108 if(flag) return query(L, mid, now << 1, flag) + query(mid + 1, R, now << 1 | 1, flag); 109 else return max(query(L, mid, now << 1, flag), query(mid + 1, R, now << 1 | 1, flag)); 110 } 111 } 112 113 ll query2(int x, int y, bool flag) 114 { 115 ll ans = flag ? 0 : -INF; 116 while(top[x] != top[y]) 117 { 118 if(deep[top[x]] < deep[top[y]]) swap(x, y); 119 if(flag) ans += query(dfsx[top[x]], dfsx[x], 1, flag); 120 else ans = max(ans, query(dfsx[top[x]], dfsx[x], 1, flag)); 121 x = fa[top[x]]; 122 } 123 if(deep[x] < deep[y]) swap(x, y); 124 if(flag) ans += query(dfsx[y], dfsx[x], 1, flag); 125 else ans = max(ans, query(dfsx[y], dfsx[x], 1, flag)); 126 return ans; 127 } 128 129 int main() 130 { 131 n = read(); 132 for(int i = 1; i < n; ++i) 133 { 134 int x = read(), y = read(); 135 v[x].push_back(y); v[y].push_back(x); 136 } 137 for(int i = 1; i <= n; ++i) w[i] = read(); 138 dfs1(1); Mem(vis); dfs2(1); 139 int q = read(); 140 build(1, cnt, 1); 141 for(int i = 1; i <= q; ++i) 142 { 143 char c[8]; scanf("%s", c); 144 if(c[0] == 'C') 145 { 146 int u = read(), t = read(); 147 update(dfsx[u], t, 1); 148 } 149 else if(c[1] == 'M') //max:0 150 { 151 int u = read(), v = read(); 152 write(query2(u, v, 0)); enter; 153 } 154 else 155 { 156 int u = read(), v = read(); 157 write(query2(u, v, 1)); enter; 158 } 159 } 160 return 0; 161 }View Code
标签:now,int,maxson,maxn,ZJOI2008,include,统计,size 来源: https://blog.51cto.com/u_15234622/2830835