[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

 

posted @ 2018-08-17 14:14  mrclr  阅读(161)  评论(0编辑  收藏  举报