第四周 2.7-2.13

寒假过半。惶恐。

 

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\n", ans);
51     }
52     return 0;
53 }
Aguin

 

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\n", ans + 1);
55     else if(solve(1)) printf("%s\n", ans + 1);
56     else puts("0");
57     return 0;
58 }
Aguin

 

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\n", 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 }
Aguin

 

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\n", ans);
57     return 0;
58 }
Aguin

 

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\n", 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\n", ans);
49     }
50     return 0;
51 }
Aguin

 

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\nTotal explored area: %.2lf\n\n", ++kase, ans);
72     }
73     return 0;
74 }
Aguin

 

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\n", ans);
77     }
78     return 0;
79 }
Aguin

 

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\n", ans);
89     }
90     return 0;
91 }
Aguin

 

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\n", 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 }
Aguin

 

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\n", tquery_sum(a, b));
160         else printf("%d\n", tquery_max(a, b));
161     }
162     return 0;
163 }
Aguin

 

posted @ 2016-02-07 12:01  Aguin  阅读(189)  评论(0编辑  收藏  举报