ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[ZJOI2008]树的统计

2021-05-29 18:55:50  阅读:160  来源: 互联网

标签:now int maxson maxn ZJOI2008 include 统计 size


嘟嘟嘟

 

一看就知道,一道树链剖分板子题,原来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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有