码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1036: [ZJOI2008]树的统计Count

时间:2015-06-11 06:56:13      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036

解:树链剖分裸题,树链剖分基础=线段树+Tarjan求LCA

树剖其实就是把树拆成链再组合起来变成线性表,然后用线段树对线性表处理就好了

树剖学习推荐博客:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html

技术分享
  1 /*
  2  * Problem:  
  3  * Author:  SHJWUDP
  4  * Created Time:  2015/6/10 星期三 23:13:56
  5  * File Name: 233.cpp
  6  * State: 
  7  * Memo: 
  8  */
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13 
 14 using namespace std;
 15 
 16 const int MaxA=3e4+7;
 17 
 18 struct Edge {
 19     int v, nt;
 20     Edge(){}
 21     Edge(int v, int nt):v(v), nt(nt){}
 22 } edges[MaxA<<1];
 23 
 24 int head[MaxA], edgeNum;
 25 
 26 struct SegmentTree {
 27     int n;
 28     struct Node {
 29         int mx;
 30         int sum;
 31     } c[MaxA<<2];
 32     int *val;
 33     int p, v;
 34     int L, R;
 35 #define lson l, m, rt<<1
 36 #define rson m+1, r, rt<<1|1
 37     
 38     void pushUp(int rt) {
 39         c[rt].mx=max(c[rt<<1].mx, c[rt<<1|1].mx);
 40         c[rt].sum=c[rt<<1].sum+c[rt<<1|1].sum;
 41     }
 42 
 43     void doBuild(int l, int r, int rt) {
 44         if(l==r) {
 45             c[rt].mx=c[rt].sum=val[l];
 46         } else {
 47             int m=(l+r)>>1;
 48             doBuild(lson);
 49             doBuild(rson);
 50             pushUp(rt);
 51         }
 52     }
 53 
 54     void build(int n, int* val) {
 55         this->n=n; this->val=val;
 56         doBuild(1, n, 1);
 57     }
 58 
 59     void doUpdate(int l, int r, int rt) {
 60         if(l==r) {
 61             c[rt].mx=c[rt].sum=v;
 62         } else {
 63             int m=(l+r)>>1;
 64             if(p<=m) doUpdate(lson);
 65             else doUpdate(rson);
 66             pushUp(rt);
 67         }
 68     }
 69 
 70     void update(int p, int v) {
 71         this->p=p; this->v=v;
 72         doUpdate(1, n, 1);
 73     }
 74     
 75     int doqmax(int l, int r, int rt) {
 76         if(L<=l && r<=R) {
 77             return c[rt].mx;
 78         } else {
 79             int m=(l+r)>>1;
 80             int res=0x80000000;
 81             if(L<=m) res=max(res, doqmax(lson));
 82             if(m<R) res=max(res, doqmax(rson));
 83             return res;
 84         }
 85     }
 86 
 87     int qmax(int L, int R) {
 88         this->L=L; this->R=R;
 89         return doqmax(1, n, 1);
 90     }
 91 
 92     int doqsum(int l, int r, int rt) {
 93         if(L<=l && r<=R) {
 94             return c[rt].sum;
 95         } else {
 96             int m=(l+r)>>1;
 97             int res=0;
 98             if(L<=m) res+=doqsum(lson);
 99             if(m<R) res+=doqsum(rson);
100             return res;
101         }
102     }
103 
104     int qsum(int L, int R) {
105         this->L=L; this->R=R;
106         return doqsum(1, n, 1);
107     }
108 #undef lson
109 #undef rson
110 } st;
111 
112 int N;
113 int oval[MaxA], val[MaxA];
114 void init() {
115     edgeNum=0;
116     memset(head, -1, sizeof(head));
117 }
118 void addEdge(int u, int v) {
119     edges[edgeNum]=Edge(v, head[u]);
120     head[u]=edgeNum++;
121 }
122 namespace LCT {
123     int fa[MaxA];
124     int son[MaxA];
125     int dep[MaxA];
126     int siz[MaxA];
127     int w[MaxA];
128     int top[MaxA];
129     int id;
130 
131     int dfs1(int u, int d) {
132         siz[u]=1; dep[u]=d; son[u]=-1;
133         for(int i=head[u]; ~i; i=edges[i].nt) {
134             Edge& e=edges[i];
135             if(e.v==fa[u]) continue;
136             fa[e.v]=u;
137             siz[u]+=dfs1(e.v, d+1);
138             if(son[u]==-1 || siz[son[u]]<siz[e.v]) son[u]=e.v;
139         }
140         return siz[u];
141     }
142 
143     void dfs2(int u, int tp) {    
144         w[u]=++id; top[u]=tp;
145         if(son[u]!=-1) dfs2(son[u], tp);
146         for(int i=head[u]; ~i; i=edges[i].nt) {
147             Edge& e=edges[i];
148             if(e.v==fa[u] || e.v==son[u]) continue;
149             dfs2(e.v, e.v);
150         }
151     }
152 
153     int query(int u, int v, int op) {
154         int res;
155         if(op==0) res=0;
156         else res=0x80000000;
157         int f1=top[u], f2=top[v];
158         while(f1!=f2) {
159             if(dep[f1]<dep[f2]) { swap(f1, f2); swap(u, v); }
160             if(op==0) res+=st.qsum(w[f1], w[u]);
161             else res=max(res, st.qmax(w[f1], w[u]));
162             u=fa[f1]; f1=top[u];
163         }
164         if(dep[u]>dep[v]) swap(u, v);
165         if(op==0) res+=st.qsum(w[u], w[v]);
166         else res=max(res, st.qmax(w[u], w[v]));
167         return res;
168     }
169 
170     void update(int p, int v) {
171         st.update(w[p], v);
172     }
173     
174     void init() {
175         int root=1;
176         id=0;
177         fa[root]=-1;
178         dfs1(root, 0);
179         dfs2(root, root);
180         for(int i=1; i<=N; i++) {
181             val[w[i]]=oval[i];
182         }
183         st.build(N, val);
184     }
185 }
186 int main() {
187 #ifndef ONLINE_JUDGE
188     freopen("in", "r", stdin);
189     //freopen("out", "w", stdout);
190 #endif
191     while(~scanf("%d", &N)) {
192         init();
193         for(int i=1; i<N; i++) {
194             int a, b;
195             scanf("%d%d", &a, &b);
196             addEdge(a, b);
197             addEdge(b, a);
198         }
199         for(int i=1; i<=N; i++) {
200             scanf("%d", &oval[i]);
201         }
202         LCT::init();
203         int Q;
204         scanf("%d", &Q);
205         while(Q--) {
206             char op[7];
207             int a, b;
208             scanf("%s%d%d", op, &a, &b);
209             if(op[0]==C) {
210                 LCT::update(a, b);
211             } else {
212                 if(op[1]==S) {
213                     printf("%d\n", LCT::query(a, b, 0));
214                 } else printf("%d\n", LCT::query(a, b, 1));
215             }
216         }
217     }
218     return 0;
219 }
2280ms

 

bzoj 1036: [ZJOI2008]树的统计Count

标签:

原文地址:http://www.cnblogs.com/shjwudp/p/4567885.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!