# BZOJ 1036: [ZJOI2008]树的统计Count 【树链剖分】

4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4

4
1
2
2
10
6
5
6
5
16

## Source

  1 #include<iostream>
2 #include<cstdio>
3 #define maxn 60000
4 using namespace std;
6 int father[maxn],son[maxn],deep[maxn];
7 struct T
8 {
9     int max_x;int sum_x;
11     T(){max_x=-0x3f3f3f3f;sum_x=0;}
12 }tree[maxn*4];
13 T work(T x,T y)
14 {
15     T ans;
16     ans.max_x=max(x.max_x,y.max_x);
17     ans.sum_x=x.sum_x+y.sum_x;
18     return ans;
19 }
20 T query(int node,int l,int r,int ql,int qr)
21 {
22     if(ql<=l && r<=qr)return tree[node];
23     int mid=(l+r)>>1;T ans;
24     if(ql<mid)ans=query(node*2,l,mid,ql,qr);
25     if(mid<qr)ans=work(ans,query(node*2+1,mid,r,ql,qr));
26     return ans;
27 }
28 void update(int node,int l,int r,int p,int x){
29     if(l+1==r){
30         tree[node].max_x=x;tree[node].sum_x=x;return ;
31     }
32     int mid=(l+r)>>1;
33     if(p<mid)update(node*2,l,mid,p,x);
34     else update(node*2+1,mid,r,p,x);
35     tree[node]=work(tree[node*2],tree[node*2+1]);
36     return ;
37 }
40 }
41 void dfs(int k,int fa)
42 {
43     deep[k]=deep[fa]+1;
44     father[k]=fa;size_k[k]=1;
46     int max_x=-1;son[k]=-1;
49     {
50         if(point[i]==fa)continue;
51         dfs(point[i],k);
52         size_k[k]+=size_k[point[i]];
53         if(size_k[point[i]]>max_x)
54         {
55             max_x=size_k[point[i]];
56             son[k]=point[i];
57         }
58     }
59 }
60 void dfs2(int k,int fa,int pa)
61 {
62     id[k]=++pos;top[k]=pa;
64     if(son[k]!=-1)dfs2(son[k],k,pa);
65     for(int i=head[k];i;i=next[i])if(point[i]!=fa && point[i]!=son[k])dfs2(point[i],k,point[i]); 69 }
70 T find(int x,int y)
71 {
72         int fx=top[x],fy=top[y];
73         T tmp;
74         while(fx!=fy)
75         {
76                 if(deep[fx]<deep[fy])swap(fx,fy),swap(x,y);
77                 tmp=work(tmp,query(1,1,pos+1,id[fx],id[x]+1));
78                 x=father[fx];fx=top[x];
79         }
80         if(deep[x]<deep[y])swap(x,y);
81         return work(tmp,query(1,1,pos+1,id[y],id[x]+1));
82 }
83 int main()
84 {
85         int n,x,y,q;
86         char ch[100];
87         scanf("%d",&n);
88         for(int i=1;i<n;i++)
89         {
90                 scanf("%d%d",&x,&y);
93         }
94         for(int i=1;i<=n;i++)scanf("%d",&w[i]);
95         scanf("%d",&q);
96         dfs(1,0);dfs2(1,1,1);
98         for(int i=1;i<=n;i++)update(1,1,pos+1,id[i],w[i]);102         while(q--)
103         {
104                 scanf("%s%d%d",ch,&x,&y);
105                 if(ch[1]=='S')
106                 {
107                         T u=find(x,y);printf("%d\n",u.sum_x);
109                 }
110                 if(ch[1]=='M')
111                 {
112                         T u=find(x,y);printf("%d\n",u.max_x);
114                 }
115                 if(ch[1]=='H')update(1,1,pos+1,id[x],y);
116         }
117         return 0;
118 }

posted @ 2015-03-20 14:57  philippica  阅读(156)  评论(0编辑  收藏  举报