树链剖分笔记
树链剖分
(不就是两个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 */