树链剖分笔记

树链剖分

(不就是两个dfs吗干嘛起这么高大上的名字)

  1 //hdu3966
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #pragma comment(linker, "/STACK:1024000000,1024000000")
  8 using namespace std;
  9 struct edge{
 10     int v,next;
 11 }a[2000001];
 12 int n,m,q,u,v,ww,now=0,tot=0,sum[2000001],cal[2000001],num[200001],head[200001],son[200001],siz[200001],dep[200001],fa[200001],top[200001],vis[200001],w[200001];
 13 char ord[10];
 14 int max(int a,int b){
 15     return a>b?a:b;
 16 }
 17 void add(int u,int v){
 18     a[++tot].v=v;
 19     a[tot].next=head[u];
 20     head[u]=tot;
 21 }
 22 void dfs1(int u,int f,int dp){
 23     int v;
 24     dep[u]=dp;
 25     fa[u]=f;
 26     siz[u]=1;
 27     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
 28         v=a[tmp].v;
 29         if(v!=f){
 30             dfs1(v,u,dp+1);
 31             siz[u]+=siz[v];
 32             if(son[u]==-1||siz[v]>siz[son[u]]){
 33                 son[u]=v;
 34             }
 35         }
 36     }
 37 }
 38 void dfs2(int u,int tp){
 39     int v;
 40     top[u]=tp;
 41     vis[u]=++now;
 42     w[vis[u]]=u;
 43     if(son[u]==-1)return;
 44     dfs2(son[u],tp);
 45     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
 46         v=a[tmp].v;
 47         if(v!=son[u]&&v!=fa[u])dfs2(v,v);
 48     }
 49 }
 50 void pushD(int rt,int len){
 51     if(cal[rt]){
 52         cal[rt<<1]+=cal[rt];
 53         cal[rt<<1|1]+=cal[rt];
 54         sum[rt<<1]+=(len-len/2)*cal[rt];
 55         sum[rt<<1|1]+=(len/2)*cal[rt];
 56         cal[rt]=0;
 57     }
 58 }
 59 void build(int l,int r,int rt){
 60     cal[rt]=0;
 61     if(l==r){
 62         sum[rt]=num[w[l]];
 63         return;
 64     }
 65     int mid=(l+r)/2;
 66     build(l,mid,rt<<1);
 67     build(mid+1,r,rt<<1|1);
 68     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
 69 }
 70 void updata(int rt,int k,int l,int r,int L,int R){
 71     if(L<=l&&r<=R){
 72         cal[rt]+=k;
 73         sum[rt]+=k*(r-l+1);
 74         return;
 75     }
 76     int mid=(l+r)/2;
 77     pushD(rt,r-l+1);
 78     if(L<=mid)updata(rt<<1,k,l,mid,L,R);
 79     if(R>mid)updata(rt<<1|1,k,mid+1,r,L,R);
 80     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
 81 }
 82 int query(int rt,int l,int r,int aa){
 83     if(l==r){
 84         return sum[rt];
 85     }
 86     int ans=0,mid=(l+r)/2;
 87     pushD(rt,r-l+1);
 88     if(aa<=mid)ans=query(rt<<1,l,mid,aa);
 89     else ans=query(rt<<1|1,mid+1,r,aa);
 90     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
 91     return ans;
 92 }
 93 void update(int u,int v,int w){
 94     while(top[u]!=top[v]){
 95         if(dep[top[u]]<dep[top[v]])swap(u,v);
 96         updata(1,w,1,n,vis[top[u]],vis[u]);
 97         u=fa[top[u]];
 98     }
 99     if(dep[u]>dep[v])swap(u,v);
100     updata(1,w,1,n,vis[u],vis[v]);
101 }
102 int main(){
103     while(scanf("%d%d%d",&n,&m,&q)!=EOF){
104         memset(head,255,sizeof(head));
105         memset(son,255,sizeof(son));
106         tot=now=0;
107         for(int i=1;i<=n;i++){
108             scanf("%d",&num[i]);
109         }
110         for(int i=1;i<=m;i++){
111             scanf("%d%d",&u,&v);
112             add(u,v);
113             add(v,u);
114         }
115         dfs1(1,0,0);
116         dfs2(1,1);
117         build(1,n,1);
118         for(int i=1;i<=q;i++){
119             scanf("%s",ord);
120             if(ord[0]=='Q'){
121                 scanf("%d",&u);
122                 printf("%d\n",query(1,1,n,vis[u]));
123             }else{
124                 scanf("%d%d%d",&u,&v,&ww);
125                 if(ord[0]=='D')ww=-ww;
126                 update(u,v,ww);
127             }
128         }
129     }
130     return 0;
131 }
132 /*
133 3 2 5
134 1 2 3
135 2 1
136 2 3
137 I 1 3 5
138 Q 2
139 D 1 2 2
140 Q 1 
141 Q 3
142 --------
143 7
144 4
145 8
146 */

 

posted @ 2018-04-25 15:38  DCDCBigBig  阅读(124)  评论(0编辑  收藏  举报