寒假过半。惶恐。
2.7
HDU 5622 KK's Chemical
只要不成环,每个点贡献就是K - 1.
所以先处理好环的。再找出每个环,数长度,算贡献。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 typedef long long LL; 6 const LL mod = 1e9 + 7; 7 int N, K, tmp, G[101][101], dep[101]; 8 LL a[101], ans; 9 10 void dfs(int p, int d) 11 { 12 if(dep[p]) 13 { 14 if(dep[p] == -1) return; 15 tmp += d - dep[p]; 16 if(!ans) ans += a[d-dep[p]]; 17 else ans = ans * a[d-dep[p]] % mod; 18 return; 19 } 20 dep[p] = d; 21 for(int i = 0; i < N; i++) 22 { 23 if(!G[p][i]) continue; 24 dfs(i, d + 1); 25 } 26 dep[p] = -1; 27 } 28 29 int main(void) 30 { 31 int T; 32 scanf("%d", &T); 33 while(T--) 34 { 35 scanf("%d %d", &N, &K); 36 memset(G, 0, sizeof(G)); 37 for(int i = 0; i < N; i++) 38 { 39 int to; 40 scanf("%d", &to); 41 G[i][to] = 1; 42 } 43 a[2] = K * (K - 1), a[3] = a[2] * (K - 2); 44 for(int i = 4; i <= N; i++) 45 a[i] = ( a[i-2] * (K - 1) + a[i-1] * (K - 2) ) % mod; 46 ans = 0LL, tmp = 0; 47 memset(dep, 0, sizeof(dep)); 48 for(int i = 0; i < N; i++) dfs(i, 1); 49 for(int i = tmp; i < N; i++) ans = ans * (K - 1) % mod; 50 printf("%I64d ", ans); 51 } 52 return 0; 53 }
2.8
CF 625 D Finals in arithmetic
感觉一直在特判吖QAQ。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn = 1e5 + 10; 6 char d[][2] = { 7 '0', '0', '1', '0', '1', '1', '2', '1', '2', '2', '3', '2', '3', '3', 8 '4', '3', '4', '4', '5', '4', '5', '5', '6', '5', '6', '6', '7', '6', 9 '7', '7', '8', '7', '8', '8', '9', '8', '9', '9' 10 }; 11 char o[maxn], ans[maxn]; 12 int cpy[maxn]; 13 14 bool solve(int p) 15 { 16 int sz = strlen(o+1); 17 for(int i = 1; i <= sz; i++) cpy[i-p] = o[i] - '0'; 18 sz -= p, ans[sz+1] = 0; 19 for(int i = 1; i <= (sz + 1) / 2; i++) 20 { 21 int x = 10 * cpy[i-1] + cpy[sz+1-i]; 22 if(x == 19 && !cpy[i]) x = 9; 23 else if(x > 18 || cpy[sz+1-i] > cpy[i]) return false; 24 if(i == 1 && !x) return false; 25 if(i == (sz + 1) / 2) 26 { 27 if(sz % 2) 28 { 29 if(x % 2) return false; 30 ans[i] = ans[sz+1-i] = x / 2 + '0'; 31 return true; 32 } 33 else 34 { 35 if(cpy[i-1] + cpy[i+1] != cpy[i]) return false; 36 ans[i] = d[x][0], ans[sz+1-i] = d[x][1]; 37 return true; 38 } 39 } 40 cpy[i] -= cpy[sz+1-i]; 41 if(cpy[i] < 0) cpy[i-1]--, cpy[i] += 10; 42 cpy[sz-i] -= cpy[i-1]; 43 cpy[i-1] = cpy[sz+1-i] = 0; 44 for(int j = sz - i; j > i; j--) 45 if(cpy[j] < 0) cpy[j] += 10, cpy[j-1]--; 46 if(cpy[i] < 0) return false; 47 ans[i] = d[x][0], ans[sz+1-i] = d[x][1]; 48 } 49 } 50 51 int main(void) 52 { 53 scanf("%s", o + 1); 54 if(solve(0)) printf("%s ", ans + 1); 55 else if(solve(1)) printf("%s ", ans + 1); 56 else puts("0"); 57 return 0; 58 }
2.9
什么都没干。
2.10
POJ 3667 Hotel
不是很懂区间合并。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 5e4 + 10; 6 int L[maxn<<2], R[maxn<<2], M[maxn<<2], tag[maxn<<2]; 7 8 void gather(int p, int m) 9 { 10 L[p] = L[p<<1]; 11 R[p] = R[p<<1|1]; 12 if(L[p] == (m - (m >> 1))) L[p] += L[p<<1|1]; 13 if(R[p] == m >> 1) R[p] += R[p<<1]; 14 M[p] = max(R[p<<1] + L[p<<1|1], max(M[p<<1], M[p<<1|1])); 15 } 16 17 void push(int p, int m) 18 { 19 if(tag[p] != -1) 20 { 21 tag[p<<1] = tag[p<<1|1] = tag[p]; 22 if(tag[p]) 23 { 24 L[p<<1] = M[p<<1] = R[p<<1] = 0; 25 L[p<<1|1] = M[p<<1|1] = R[p<<1|1] = 0; 26 } 27 else 28 { 29 L[p<<1] = M[p<<1] = R[p<<1] = m - (m >> 1); 30 L[p<<1|1] = M[p<<1|1] = R[p<<1|1] = m >> 1; 31 } 32 tag[p] = -1; 33 } 34 } 35 36 void build(int p, int l, int r) 37 { 38 tag[p] = -1; 39 if(l < r) 40 { 41 int mid = (l + r) >> 1; 42 build(p<<1, l, mid); 43 build(p<<1|1, mid + 1, r); 44 gather(p, r - l + 1); 45 } 46 else L[p] = R[p] = M[p] = 1; 47 } 48 49 void modify(int p, int tl, int tr, int l, int r, int v) 50 { 51 if(tr < l || r < tl) return; 52 if(l <= tl && tr <= r) 53 { 54 tag[p] = v; 55 if(v) L[p] = M[p] = R[p] = 0; 56 else L[p] = M[p] = R[p] = tr - tl + 1; 57 return; 58 } 59 push(p, tr - tl + 1); 60 int mid = (tl + tr) >> 1; 61 modify(p<<1, tl, mid, l, r, v); 62 modify(p<<1|1, mid+1, tr, l, r, v); 63 gather(p, tr - tl + 1); 64 } 65 66 int query(int p, int tl, int tr, int m) 67 { 68 if(tl == tr) return tl; 69 push(p, tr - tl + 1); 70 int mid = (tl + tr) >> 1; 71 if(M[p<<1] >= m) return query(p<<1, tl, mid, m); 72 if(R[p<<1] + L[p<<1|1] >= m) return mid - R[p<<1] + 1; 73 return query(p<<1|1, mid + 1, tr, m); 74 } 75 76 int main(void) 77 { 78 int N, m; 79 scanf("%d %d", &N, &m); 80 build(1, 1, N); 81 while(m--) 82 { 83 int op, a, b; 84 scanf("%d", &op); 85 if(op == 1) 86 { 87 scanf("%d", &a); 88 if(M[1] < a) puts("0"); 89 else 90 { 91 b = query(1, 1, N, a); 92 printf("%d ", b); 93 modify(1, 1, N, b, b + a - 1, 1); 94 } 95 } 96 else 97 { 98 scanf("%d %d", &a, &b); 99 modify(1, 1, N, a, a + b - 1, 0); 100 } 101 } 102 return 0; 103 }
2.11
CF 622 E Ants in Leaves
不是很懂贪心。
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 5e5 + 10; 7 int cnt, h[maxn]; 8 vector<int> tmp; 9 10 struct edge 11 { 12 int to, pre; 13 } e[maxn<<1]; 14 15 void add(int from, int to) 16 { 17 cnt++; 18 e[cnt].pre = h[from]; 19 e[cnt].to = to; 20 h[from] = cnt; 21 } 22 23 void dfs(int p, int f, int d) 24 { 25 int son = 0; 26 for(int i = h[p]; i; i = e[i].pre) 27 { 28 int to = e[i].to; 29 if(to == f) continue; 30 dfs(to, p, d + 1); 31 son++; 32 } 33 if(!son) tmp.push_back(d); 34 } 35 36 int main(void) 37 { 38 int n; 39 scanf("%d", &n); 40 for(int i = 1; i < n; i++) 41 { 42 int u, v; 43 scanf("%d %d", &u, &v); 44 add(u, v), add(v, u); 45 } 46 int ans = 0; 47 for(int i = h[1]; i; i = e[i].pre) 48 { 49 tmp.clear(); 50 dfs(e[i].to, 1, 0); 51 sort(tmp.begin(), tmp.end()); 52 int sz = tmp.size(), cur = -1; 53 for(int j = 0; j < sz; j++) cur = max(cur + 1, tmp[j]); 54 ans = max(ans, cur + 1); 55 } 56 printf("%d ", ans); 57 return 0; 58 }
CF 622 F The Sum of the k-th Powers
拉格朗日插值懵逼。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long LL; 5 const LL mod = 1e9 + 7; 6 const int maxn = 1e6 + 10; 7 LL pow_i_k[maxn], p[maxn]; 8 9 LL qpow(LL a, int b) 10 { 11 LL ret = 1LL; 12 while(b) 13 { 14 if(b & 1) ret = ret * a % mod; 15 a = a * a % mod; 16 b >>= 1; 17 } 18 return ret; 19 } 20 21 LL inv(LL x) 22 { 23 return qpow(x, mod - 2); 24 } 25 26 int main(void) 27 { 28 LL n, k; 29 scanf("%I64d %I64d", &n, &k); 30 for(int i = 1; i <= k + 1; i++) pow_i_k[i] = qpow(i, k); 31 for(int i = 1; i <= k + 1; i++) p[i] = (p[i-1] + pow_i_k[i]) % mod; 32 if(n <= k + 1) printf("%I64d ", p[n]); 33 else 34 { 35 LL ans = 0LL, tmp, a = 1LL, b = 1LL; 36 for(int i = 1; i <= k + 1; i++) a = a * (n - i) % mod; 37 for(int i = 1; i <= k + 1; i++) b = (b * (-i) % mod + mod) % mod; 38 tmp = a * inv(b) % mod; 39 for(int i = 1; i <= k + 1; i++) 40 { 41 tmp = tmp * (n - i + 1) % mod; 42 tmp = tmp * inv(n - i) % mod; 43 tmp = tmp * inv(i) % mod; 44 tmp = tmp * (k - i + 2) % mod; 45 tmp = (mod - tmp) % mod; 46 ans = ( ans + p[i] * tmp % mod ) % mod; 47 } 48 printf("%I64d ", ans); 49 } 50 return 0; 51 }
2.12
HDU 1542 Atlantis
不是很懂扫描线。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 2222; 7 double a[maxn]; 8 9 struct seg 10 { 11 int f; 12 double l, r, h; 13 seg(){} 14 seg(double L, double R, double H, int F): l(L), r(R), h(H), f(F){} 15 }S[maxn]; 16 17 bool cmp(seg A, seg B) 18 { 19 return A.h < B.h; 20 } 21 22 int cnt[maxn<<2]; 23 double sum[maxn<<2]; 24 25 void gather(int p, int tl, int tr) 26 { 27 if(cnt[p]) sum[p] = a[tr] - a[tl-1]; 28 else if(tl == tr) sum[p] = 0; 29 else sum[p] = sum[p<<1] + sum[p<<1|1]; 30 } 31 32 void modify(int p, int tl, int tr, int l, int r, int v) 33 { 34 if(tr < l || r < tl) return; 35 if(l <= tl && tr <= r) cnt[p] += v; 36 else 37 { 38 int mid = (tl + tr) >> 1; 39 modify(p<<1, tl, mid, l, r, v); 40 modify(p<<1|1, mid+1, tr, l, r, v); 41 } 42 gather(p, tl, tr); 43 } 44 45 int main(void) 46 { 47 int n, kase = 0; 48 while(~scanf("%d", &n) && n) 49 { 50 for(int i = 0; i < n; i++) 51 { 52 double x1, y1, x2, y2; 53 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 54 a[i] = x1, a[i+n] = x2; 55 S[i] = seg(x1, x2, y1, 1); 56 S[i+n] = seg(x1, x2, y2, -1); 57 } 58 sort(a, a + 2 * n); 59 int sz = unique(a, a + 2 * n) - a; 60 sort(S, S + 2 * n, cmp); 61 memset(cnt, 0, sizeof(cnt)); 62 memset(sum, 0, sizeof(sum)); 63 double ans = 0.0; 64 for(int i = 0; i < 2 * n - 1; i++) 65 { 66 int l = lower_bound(a, a + sz, S[i].l) - a + 1; 67 int r = lower_bound(a, a + sz, S[i].r) - a; 68 modify(1, 1, sz, l, r, S[i].f); 69 ans += sum[1] * (S[i+1].h - S[i].h); 70 } 71 printf("Test case #%d Total explored area: %.2lf ", ++kase, ans); 72 } 73 return 0; 74 }
HDU 1828 Picture
不是很懂扫描线。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 22222; 7 8 struct seg 9 { 10 int l, r, h, f; 11 seg(){} 12 seg(int L, int R, int H, int F): l(L), r(R), h(H), f(F){} 13 }S[maxn]; 14 15 bool cmp(seg A, seg B) 16 { 17 if(A.h != B.h) return A.h < B.h; 18 return A.f > B.f; 19 } 20 21 int cnt[maxn<<2], sum[maxn<<2]; 22 int vtc[maxn<<2], lbd[maxn<<2], rbd[maxn<<2]; 23 void gather(int p, int tl, int tr) 24 { 25 if(cnt[p]) 26 { 27 vtc[p] = 2; 28 lbd[p] = rbd[p] = 1; 29 sum[p] = tr - tl + 1; 30 } 31 else if(tl == tr) sum[p] = vtc[p] = lbd[p] = rbd[p] = 0; 32 else 33 { 34 lbd[p] = lbd[p<<1]; 35 rbd[p] = rbd[p<<1|1]; 36 sum[p] = sum[p<<1] + sum[p<<1|1]; 37 vtc[p] = vtc[p<<1] + vtc[p<<1|1]; 38 if(rbd[p<<1] && lbd[p<<1|1]) vtc[p] -= 2; 39 } 40 } 41 42 void modify(int p, int tl, int tr, int l, int r, int v) 43 { 44 if(tr < l || r < tl) return; 45 if(l <= tl && tr <= r) cnt[p] += v; 46 else 47 { 48 int mid = (tl + tr) >> 1; 49 modify(p<<1, tl, mid, l, r, v); 50 modify(p<<1|1, mid+1, tr, l, r, v); 51 } 52 gather(p, tl, tr); 53 } 54 55 int main(void) 56 { 57 int n; 58 while(~scanf("%d", &n)) 59 { 60 for(int i = 0; i < n; i++) 61 { 62 int x1, y1, x2, y2; 63 scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 64 S[i] = seg(x1, x2, y1, 1); 65 S[i+n] = seg(x1, x2, y2, -1); 66 } 67 sort(S, S + 2 * n, cmp); 68 int ans = 0, last = 0; 69 for(int i = 0; i < 2 * n; i++) 70 { 71 modify(1, -10000, 10000, S[i].l, S[i].r - 1, S[i].f); 72 ans += vtc[1] * (S[i+1].h - S[i].h); 73 ans += abs(sum[1] - last); 74 last = sum[1]; 75 } 76 printf("%d ", ans); 77 } 78 return 0; 79 }
HDU 1255 覆盖的面积
虽然不是很懂扫描线但是和上上题一样。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 2222; 7 double a[maxn]; 8 9 struct seg 10 { 11 int f; 12 double l, r, h; 13 seg(){} 14 seg(double L, double R, double H, int F): l(L), r(R), h(H), f(F){} 15 }S[maxn]; 16 17 bool cmp(seg A, seg B) 18 { 19 return A.h < B.h; 20 } 21 22 int cnt[maxn<<2]; 23 double sum1[maxn<<2], sum2[maxn<<2]; 24 25 void gather(int p, int tl, int tr) 26 { 27 if(cnt[p] > 1) 28 { 29 sum1[p] = 0; 30 sum2[p] = a[tr] - a[tl-1]; 31 } 32 else if(cnt[p]) 33 { 34 sum2[p] = sum1[p<<1] + sum1[p<<1|1] + sum2[p<<1] + sum2[p<<1|1]; 35 sum1[p] = a[tr] - a[tl-1] - sum2[p]; 36 } 37 else if(tl == tr) sum1[p] = sum2[p] = 0; 38 else 39 { 40 sum1[p] = sum1[p<<1] + sum1[p<<1|1]; 41 sum2[p] = sum2[p<<1] + sum2[p<<1|1]; 42 } 43 } 44 45 void modify(int p, int tl, int tr, int l, int r, int v) 46 { 47 if(tr < l || r < tl) return; 48 if(l <= tl && tr <= r) cnt[p] += v; 49 else 50 { 51 int mid = (tl + tr) >> 1; 52 modify(p<<1, tl, mid, l, r, v); 53 modify(p<<1|1, mid+1, tr, l, r, v); 54 } 55 gather(p, tl, tr); 56 } 57 58 int main(void) 59 { 60 int T; 61 scanf("%d", &T); 62 while(T--) 63 { 64 int n; 65 scanf("%d", &n); 66 for(int i = 0; i < n; i++) 67 { 68 double x1, y1, x2, y2; 69 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 70 a[i] = x1, a[i+n] = x2; 71 S[i] = seg(x1, x2, y1, 1); 72 S[i+n] = seg(x1, x2, y2, -1); 73 } 74 sort(a, a + 2 * n); 75 int sz = unique(a, a + 2 * n) - a; 76 sort(S, S + 2 * n, cmp); 77 memset(cnt, 0, sizeof(cnt)); 78 memset(sum1, 0, sizeof(sum1)); 79 memset(sum2, 0, sizeof(sum2)); 80 double ans = 0.0; 81 for(int i = 0; i < 2 * n - 1; i++) 82 { 83 int l = lower_bound(a, a + sz, S[i].l) - a + 1; 84 int r = lower_bound(a, a + sz, S[i].r) - a; 85 modify(1, 1, sz, l, r, S[i].f); 86 ans += sum2[1] * (S[i+1].h - S[i].h); 87 } 88 printf("%.2lf ", ans); 89 } 90 return 0; 91 }
2.13
SPOJ QTREE Query on a tree
不是很懂树链剖分。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 2e5 + 10; 7 int fa[maxn], dep[maxn], sz[maxn], son[maxn]; 8 int tot, top[maxn], tid[maxn], id[maxn]; 9 int cnt, h[maxn]; 10 int M[maxn<<2]; 11 int N, a[maxn], eid[maxn]; 12 13 struct edge 14 { 15 int to, pre, cost, idx; 16 } e[maxn<<1]; 17 18 void init() 19 { 20 cnt = tot = 0; 21 memset(h, 0, sizeof(h)); 22 } 23 24 void add(int from, int to, int cost, int idx) 25 { 26 cnt++; 27 e[cnt].pre = h[from]; 28 e[cnt].to = to; 29 e[cnt].cost = cost; 30 e[cnt].idx = idx; 31 h[from] = cnt; 32 } 33 34 void dfs1(int p, int f, int d) 35 { 36 fa[p] = f, dep[p] = d; 37 sz[p] = 1, son[p] = 0; 38 for(int i = h[p]; i; i = e[i].pre) 39 { 40 int to = e[i].to; 41 if(to == f) continue; 42 dfs1(to, p, d + 1); 43 sz[p] += sz[to]; 44 if(!son[p] || sz[to] > sz[son[p]]) son[p] = to; 45 } 46 } 47 48 void dfs2(int p, int anc) 49 { 50 top[p] = anc; 51 tid[p] = ++tot; 52 id[tot] = p; 53 if(!son[p]) return; 54 dfs2(son[p], anc); 55 for(int i = h[p]; i; i = e[i].pre) 56 { 57 int to = e[i].to; 58 if(to == son[p]) eid[e[i].idx] = tid[to]; 59 if(to == fa[p] || to == son[p]) continue; 60 dfs2(to, to); 61 eid[e[i].idx] = tid[to]; 62 } 63 } 64 65 void gather(int p) 66 { 67 M[p] = max(M[p<<1], M[p<<1|1]); 68 } 69 70 void build(int p, int l, int r) 71 { 72 if(l < r) 73 { 74 int mid = (l + r) >> 1; 75 build(p<<1, l, mid); 76 build(p<<1|1, mid + 1, r); 77 gather(p); 78 } 79 else M[p] = a[l]; 80 } 81 82 void modify(int p, int tl, int tr, int x, int v) 83 { 84 if(tr < x || x < tl) return; 85 if(tl == tr) {M[p] = v; return;} 86 int mid = (tl + tr) >> 1; 87 modify(p<<1, tl, mid, x, v); 88 modify(p<<1|1, mid+1, tr, x, v); 89 gather(p); 90 } 91 92 int query(int p, int tl, int tr, int l, int r) 93 { 94 if(tr < l || r < tl) return 0; 95 if(l <= tl && tr <= r) return M[p]; 96 int mid = (tl + tr) >> 1; 97 int ret = query(p<<1, tl, mid, l, r); 98 ret = max(ret, query(p<<1|1, mid+1, tr, l, r)); 99 return ret; 100 } 101 102 int tquery(int x, int y) 103 { 104 int ret = 0; 105 while(top[x] != top[y]) 106 { 107 if(dep[top[x]] < dep[top[y]]) swap(x, y); 108 ret = max(ret, query(1, 1, N, tid[top[x]], tid[x])); 109 x = fa[top[x]]; 110 } 111 if(dep[x] > dep[y]) swap(x, y); 112 ret = max(ret, query(1, 1, N, tid[son[x]], tid[y])); 113 return ret; 114 } 115 116 int main(void) 117 { 118 int T; 119 scanf("%d", &T); 120 while(T--) 121 { 122 init(); 123 scanf("%d", &N); 124 for(int i = 1; i < N; i++) 125 { 126 int a, b, c; 127 scanf("%d %d %d", &a, &b, &c); 128 add(a, b, c, i), add(b, a, c, i); 129 } 130 dfs1(1, 0, 0); 131 dfs2(1, 1); 132 for(int i = 1; i <= cnt; i++) a[eid[e[i].idx]] = e[i].cost; 133 build(1, 1, N); 134 while(1) 135 { 136 int a, b; 137 char op[10]; 138 scanf("%s", op); 139 if(op[0] == 'D') break; 140 if(op[0] == 'Q') 141 { 142 scanf("%d %d", &a, &b); 143 printf("%d ", tquery(a, b)); 144 } 145 else 146 { 147 scanf("%d %d", &a, &b); 148 modify(1, 1, N, eid[a], b); 149 } 150 } 151 } 152 return 0; 153 }
BZOJ 1036 [ZJOI2008]树的统计Count
自信抄板哈哈哈。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int maxn = 2e5 + 10; 7 int fa[maxn], dep[maxn], sz[maxn], son[maxn]; 8 int tot, top[maxn], tid[maxn], id[maxn]; 9 int cnt, h[maxn]; 10 int M[maxn<<2], sum[maxn]; 11 int N, a[maxn]; 12 13 struct edge 14 { 15 int to, pre; 16 } e[maxn<<1]; 17 18 void init() 19 { 20 cnt = tot = 0; 21 memset(h, 0, sizeof(h)); 22 } 23 24 void add(int from, int to) 25 { 26 cnt++; 27 e[cnt].pre = h[from]; 28 e[cnt].to = to; 29 h[from] = cnt; 30 } 31 32 void dfs1(int p, int f, int d) 33 { 34 fa[p] = f, dep[p] = d; 35 sz[p] = 1, son[p] = 0; 36 for(int i = h[p]; i; i = e[i].pre) 37 { 38 int to = e[i].to; 39 if(to == f) continue; 40 dfs1(to, p, d + 1); 41 sz[p] += sz[to]; 42 if(!son[p] || sz[to] > sz[son[p]]) son[p] = to; 43 } 44 } 45 46 void dfs2(int p, int anc) 47 { 48 top[p] = anc; 49 tid[p] = ++tot; 50 id[tot] = p; 51 if(!son[p]) return; 52 dfs2(son[p], anc); 53 for(int i = h[p]; i; i = e[i].pre) 54 { 55 int to = e[i].to; 56 if(to == fa[p] || to == son[p]) continue; 57 dfs2(to, to); 58 } 59 } 60 61 void gather(int p) 62 { 63 M[p] = max(M[p<<1], M[p<<1|1]); 64 sum[p] = sum[p<<1] + sum[p<<1|1]; 65 } 66 67 void build(int p, int l, int r) 68 { 69 if(l < r) 70 { 71 int mid = (l + r) >> 1; 72 build(p<<1, l, mid); 73 build(p<<1|1, mid + 1, r); 74 gather(p); 75 } 76 else M[p] = sum[p] = a[id[l]]; 77 } 78 79 void modify(int p, int tl, int tr, int x, int v) 80 { 81 if(tr < x || x < tl) return; 82 if(tl == tr) {M[p] = sum[p] = v; return;} 83 int mid = (tl + tr) >> 1; 84 modify(p<<1, tl, mid, x, v); 85 modify(p<<1|1, mid+1, tr, x, v); 86 gather(p); 87 } 88 89 int query_sum(int p, int tl, int tr, int l, int r) 90 { 91 if(tr < l || r < tl) return 0; 92 if(l <= tl && tr <= r) return sum[p]; 93 int mid = (tl + tr) >> 1; 94 int ret = query_sum(p<<1, tl, mid, l, r); 95 ret += query_sum(p<<1|1, mid+1, tr, l, r); 96 return ret; 97 } 98 99 int query_max(int p, int tl, int tr, int l, int r) 100 { 101 if(tr < l || r < tl) return -30000; 102 if(l <= tl && tr <= r) return M[p]; 103 int mid = (tl + tr) >> 1; 104 int ret = query_max(p<<1, tl, mid, l, r); 105 ret = max(ret, query_max(p<<1|1, mid+1, tr, l, r)); 106 return ret; 107 } 108 109 int tquery_sum(int x, int y) 110 { 111 int ret = 0; 112 while(top[x] != top[y]) 113 { 114 if(dep[top[x]] < dep[top[y]]) swap(x, y); 115 ret += query_sum(1, 1, N, tid[top[x]], tid[x]); 116 x = fa[top[x]]; 117 } 118 if(dep[x] > dep[y]) swap(x, y); 119 ret += query_sum(1, 1, N, tid[x], tid[y]); 120 return ret; 121 } 122 123 int tquery_max(int x, int y) 124 { 125 int ret = -30000; 126 while(top[x] != top[y]) 127 { 128 if(dep[top[x]] < dep[top[y]]) swap(x, y); 129 ret = max(ret, query_max(1, 1, N, tid[top[x]], tid[x])); 130 x = fa[top[x]]; 131 } 132 if(dep[x] > dep[y]) swap(x, y); 133 ret = max(ret, query_max(1, 1, N, tid[x], tid[y])); 134 return ret; 135 } 136 137 int main(void) 138 { 139 init(); 140 scanf("%d", &N); 141 for(int i = 1; i < N; i++) 142 { 143 int a, b; 144 scanf("%d %d", &a, &b); 145 add(a, b), add(b, a); 146 } 147 for(int i = 1; i <= N; i++) scanf("%d", a + i); 148 dfs1(1, 0, 0); 149 dfs2(1, 1); 150 build(1, 1, N); 151 int q; 152 scanf("%d", &q); 153 while(q--) 154 { 155 int a, b; 156 char op[10]; 157 scanf("%s %d %d", op, &a, &b); 158 if(op[0] == 'C') modify(1, 1, N, tid[a], b); 159 else if(op[1] == 'S') printf("%d ", tquery_sum(a, b)); 160 else printf("%d ", tquery_max(a, b)); 161 } 162 return 0; 163 }