树链剖分
Heavy-Light Decomposition 有图有真相:http://blog.sina.com.cn/s/blog_a19ad7a10102uz6f.html
375. Query on a tree http://www.spoj.com/problems/QTREE/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 const int M=10010; 12 struct IN{ 13 int u,v,w; 14 }e[M]; 15 struct G{ 16 struct E{ 17 int v,next; 18 }e[M<<1]; 19 int le,head[M]; 20 void init(){ 21 le=0; 22 mt(head,-1); 23 } 24 void add(int u,int v){ 25 e[le].v=v; 26 e[le].next=head[u]; 27 head[u]=le++; 28 } 29 }g; 30 int n,fa[M],dep[M],num[M],son[M],sid[M],top[M]; 31 void dfs(int u){ 32 num[u]=1; 33 son[u]=0; 34 for(int i=g.head[u];~i;i=g.e[i].next){ 35 int v=g.e[i].v; 36 if(v!=fa[u]){ 37 fa[v]=u; 38 dep[v]=dep[u]+1; 39 dfs(v); 40 if(num[son[u]]<num[v]) son[u]=v; 41 num[u]+=num[v]; 42 } 43 } 44 } 45 void get(int u,int Top){ 46 sid[u]=++n; 47 top[u]=Top; 48 if(son[u]) get(son[u],Top); 49 for(int i=g.head[u];~i;i=g.e[i].next){ 50 int v=g.e[i].v; 51 if(v!=fa[u]&&v!=son[u]){ 52 get(v,v); 53 } 54 } 55 } 56 int tree[M<<2]; 57 void pushup(int rt){ 58 tree[rt]=max(tree[rt<<1],tree[rt<<1|1]); 59 } 60 void update(int x,int val,lrrt){ 61 if(L==R){ 62 tree[rt]=val; 63 return ; 64 } 65 imid; 66 if(mid>=x) update(x,val,lson); 67 else update(x,val,rson); 68 pushup(rt); 69 } 70 int query(int x,int y,lrrt){ 71 if(x<=L&&R<=y) return tree[rt]; 72 imid; 73 int ans=0; 74 if(mid>=x) ans=max(ans,query(x,y,lson)); 75 if(mid<y) ans=max(ans,query(x,y,rson)); 76 return ans; 77 } 78 int solve(int x,int y){ 79 int tx=top[x],ty=top[y],ans=0; 80 while(tx!=ty){ 81 if(dep[tx]<dep[ty]){ 82 swap(tx,ty); 83 swap(x,y); 84 } 85 ans=max(ans,query(sid[tx],sid[x],iall)); 86 x=fa[tx]; 87 tx=top[x]; 88 } 89 if(x==y) return ans; 90 if(dep[x]>dep[y]) swap(x,y); 91 return max(ans,query(sid[son[x]],sid[y],iall)); 92 } 93 int main(){ 94 int t,m; 95 while(~scanf("%d",&t)){ 96 while(t--){ 97 scanf("%d",&m); 98 g.init(); 99 for(int i=1;i<m;i++){ 100 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); 101 g.add(e[i].u,e[i].v); 102 g.add(e[i].v,e[i].u); 103 } 104 n=fa[1]=dep[1]=num[0]=1; 105 dfs(1); 106 get(1,1); 107 mt(tree,0); 108 for(int i=1;i<m;i++){ 109 if(dep[e[i].u]>dep[e[i].v]){ 110 swap(e[i].u,e[i].v); 111 } 112 update(sid[e[i].v],e[i].w,iall); 113 } 114 char op[8]; 115 int x,y; 116 while(scanf("%s",op),op[0]!='D'){ 117 scanf("%d%d",&x,&y); 118 if(op[0]=='C') update(sid[e[x].v],y,iall); 119 else printf("%d\n",solve(x,y)); 120 } 121 } 122 } 123 return 0; 124 }
Tree http://poj.org/problem?id=3237
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 const int inf=0x7fffffff; 12 const int M=10010; 13 struct IN{ 14 int u,v,w; 15 }e[M]; 16 struct G{ 17 struct E{ 18 int v,next; 19 }e[M<<1]; 20 int le,head[M]; 21 void init(){ 22 le=0; 23 mt(head,-1); 24 } 25 void add(int u,int v){ 26 e[le].v=v; 27 e[le].next=head[u]; 28 head[u]=le++; 29 } 30 }g; 31 int n,fa[M],dep[M],num[M],son[M],top[M],sid[M]; 32 void dfs(int u){ 33 num[u]=1; 34 son[u]=0; 35 for(int i=g.head[u];~i;i=g.e[i].next){ 36 int v=g.e[i].v; 37 if(v!=fa[u]){ 38 fa[v]=u; 39 dep[v]=dep[u]+1; 40 dfs(v); 41 if(num[son[u]]<num[v]) son[u]=v; 42 num[u]+=num[v]; 43 } 44 } 45 } 46 void get(int u,int Top){ 47 sid[u]=++n; 48 top[u]=Top; 49 if(son[u]) get(son[u],Top); 50 for(int i=g.head[u];~i;i=g.e[i].next){ 51 int v=g.e[i].v; 52 if(v!=fa[u]&&v!=son[u]){ 53 get(v,v); 54 } 55 } 56 } 57 struct T{ 58 int big,sma,lazy; 59 }tree[M<<2]; 60 void pushup(int rt){ 61 tree[rt].big=max(tree[rt<<1].big,tree[rt<<1|1].big); 62 tree[rt].sma=min(tree[rt<<1].sma,tree[rt<<1|1].sma); 63 } 64 void pushdown(int rt){ 65 if(tree[rt].lazy){ 66 tree[rt<<1].lazy^=1; 67 tree[rt<<1|1].lazy^=1; 68 tree[rt].lazy=0; 69 tree[rt<<1].big*=-1; 70 tree[rt<<1].sma*=-1; 71 swap(tree[rt<<1].big,tree[rt<<1].sma); 72 tree[rt<<1|1].big*=-1; 73 tree[rt<<1|1].sma*=-1; 74 swap(tree[rt<<1|1].big,tree[rt<<1|1].sma); 75 } 76 } 77 void update(int x,int val,lrrt){ 78 if(L==R){ 79 tree[rt].big=tree[rt].sma=val; 80 return ; 81 } 82 pushdown(rt); 83 imid; 84 if(mid>=x) update(x,val,lson); 85 else update(x,val,rson); 86 pushup(rt); 87 } 88 void change(int x,int y,lrrt){ 89 if(x<=L&&R<=y){ 90 tree[rt].lazy^=1; 91 tree[rt].big*=-1; 92 tree[rt].sma*=-1; 93 swap(tree[rt].big,tree[rt].sma); 94 return ; 95 } 96 pushdown(rt); 97 imid; 98 if(mid>=x) change(x,y,lson); 99 if(mid<y) change(x,y,rson); 100 pushup(rt); 101 } 102 void work(int x,int y){ 103 int tx=top[x],ty=top[y]; 104 while(tx!=ty){ 105 if(dep[tx]<dep[ty]){ 106 swap(tx,ty); 107 swap(x,y); 108 } 109 change(sid[tx],sid[x],iall); 110 x=fa[tx]; 111 tx=top[x]; 112 } 113 if(x==y) return ; 114 if(dep[x]>dep[y]) swap(x,y); 115 change(sid[son[x]],sid[y],iall); 116 } 117 int query(int x,int y,lrrt){ 118 if(x<=L&&R<=y) return tree[rt].big; 119 pushdown(rt); 120 imid; 121 int ans=-inf; 122 if(mid>=x) ans=max(ans,query(x,y,lson)); 123 if(mid<y) ans=max(ans,query(x,y,rson)); 124 return ans; 125 } 126 int getmax(int x,int y){ 127 int tx=top[x],ty=top[y],ans=-inf; 128 while(tx!=ty){ 129 if(dep[tx]<dep[ty]){ 130 swap(tx,ty); 131 swap(x,y); 132 } 133 ans=max(ans,query(sid[tx],sid[x],iall)); 134 x=fa[tx]; 135 tx=top[x]; 136 } 137 if(x==y) return ans; 138 if(dep[x]>dep[y]) swap(x,y); 139 return max(ans,query(sid[son[x]],sid[y],iall)); 140 } 141 int main(){ 142 int t,m; 143 while(~scanf("%d",&t)){ 144 while(t--){ 145 scanf("%d",&m); 146 g.init(); 147 for(int i=1;i<m;i++){ 148 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); 149 g.add(e[i].u,e[i].v); 150 g.add(e[i].v,e[i].u); 151 } 152 n=fa[1]=dep[1]=num[0]=0; 153 dfs(1); 154 get(1,1); 155 mt(tree,0); 156 for(int i=1;i<m;i++){ 157 if(dep[e[i].u]>dep[e[i].v]){ 158 swap(e[i].u,e[i].v); 159 } 160 update(sid[e[i].v],e[i].w,iall); 161 } 162 char op[8]; 163 int x,y; 164 while(scanf("%s",op),op[0]!='D'){ 165 scanf("%d%d",&x,&y); 166 if(op[0]=='C') update(sid[e[x].v],y,iall); 167 else if(op[0]=='N') work(x,y); 168 else printf("%d\n",getmax(x,y)); 169 } 170 } 171 } 172 return 0; 173 }
Aragorn's Story http://acm.hdu.edu.cn/showproblem.php?pid=3966
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 const int M=50010; 12 struct G{ 13 struct E{ 14 int v,next; 15 }e[M<<1]; 16 int le,head[M]; 17 void init(){ 18 le=0; 19 mt(head,-1); 20 } 21 void add(int u,int v){ 22 e[le].v=v; 23 e[le].next=head[u]; 24 head[u]=le++; 25 } 26 }g; 27 int n,val[M],fa[M],dep[M],num[M],son[M],top[M],sid[M]; 28 void dfs(int u){ 29 num[u]=1; 30 son[u]=0; 31 for(int i=g.head[u];~i;i=g.e[i].next){ 32 int v=g.e[i].v; 33 if(v!=fa[u]){ 34 fa[v]=u; 35 dep[v]=dep[u]+1; 36 dfs(v); 37 if(num[son[u]]<num[v]) son[u]=v; 38 num[u]+=num[v]; 39 } 40 } 41 } 42 void get(int u,int Top){ 43 sid[u]=++n; 44 top[u]=Top; 45 if(son[u]) get(son[u],top[u]); 46 for(int i=g.head[u];~i;i=g.e[i].next){ 47 int v=g.e[i].v; 48 if(v!=fa[u]&&v!=son[u]){ 49 get(v,v); 50 } 51 } 52 } 53 int tree[M<<2]; 54 void pushdown(int rt){ 55 if(tree[rt]){ 56 tree[rt<<1]+=tree[rt]; 57 tree[rt<<1|1]+=tree[rt]; 58 tree[rt]=0; 59 } 60 } 61 void update(int x,int y,int z,lrrt){ 62 if(x<=L&&R<=y){ 63 tree[rt]+=z; 64 return ; 65 } 66 imid; 67 pushdown(rt); 68 if(mid>=x) update(x,y,z,lson); 69 if(mid<y) update(x,y,z,rson); 70 } 71 int query(int x,lrrt){ 72 if(L==R) return tree[rt]; 73 pushdown(rt); 74 imid; 75 if(mid>=x) return query(x,lson); 76 return query(x,rson); 77 } 78 void work(int x,int y,int z){ 79 int tx=top[x],ty=top[y]; 80 while(tx!=ty){ 81 if(dep[tx]<dep[ty]){ 82 swap(tx,ty); 83 swap(x,y); 84 } 85 update(sid[tx],sid[x],z,iall); 86 x=fa[tx]; 87 tx=top[x]; 88 } 89 if(dep[x]>dep[y]) swap(x,y); 90 update(sid[x],sid[y],z,iall); 91 } 92 int main(){ 93 int m,p; 94 while(~scanf("%d%d%d",&n,&m,&p)){ 95 for(int i=1;i<=n;i++){ 96 scanf("%d",&val[i]); 97 } 98 g.init(); 99 for(int i=0,u,v;i<m;i++){ 100 scanf("%d%d",&u,&v); 101 g.add(u,v); 102 g.add(v,u); 103 } 104 n=fa[1]=dep[1]=num[0]=0; 105 dfs(1); 106 get(1,1); 107 mt(tree,0); 108 for(int i=1;i<=m+1;i++){ 109 update(sid[i],sid[i],val[i],iall); 110 } 111 char op[2]; 112 while(p--){ 113 int x,y,z; 114 scanf("%s%d",op,&x); 115 if(op[0]=='Q'){ 116 printf("%d\n",query(sid[x],iall)); 117 continue; 118 } 119 scanf("%d%d",&y,&z); 120 if(op[0]=='D') z*=-1; 121 work(x,y,z); 122 } 123 } 124 return 0; 125 }
1036: [ZJOI2008]树的统计Count http://www.lydsy.com/JudgeOnline/problem.php?id=1036
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 const int inf=0x7fffffff; 12 const int M=30010; 13 struct G{ 14 struct E{ 15 int v,next; 16 }e[M<<1]; 17 int le,head[M]; 18 void init(){ 19 le=0; 20 mt(head,-1); 21 } 22 void add(int u,int v){ 23 e[le].v=v; 24 e[le].next=head[u]; 25 head[u]=le++; 26 } 27 }g; 28 int n,fa[M],dep[M],num[M],son[M],sid[M],top[M]; 29 void dfs(int u){ 30 num[u]=1; 31 son[u]=0; 32 for(int i=g.head[u];~i;i=g.e[i].next){ 33 int v=g.e[i].v; 34 if(v!=fa[u]){ 35 fa[v]=u; 36 dep[v]=dep[u]+1; 37 dfs(v); 38 if(num[son[u]]<num[v]) son[u]=v; 39 num[u]+=num[v]; 40 } 41 } 42 } 43 void get(int u,int Top){ 44 sid[u]=++n; 45 top[u]=Top; 46 if(son[u]) get(son[u],Top); 47 for(int i=g.head[u];~i;i=g.e[i].next){ 48 int v=g.e[i].v; 49 if(v!=fa[u]&&v!=son[u]){ 50 get(v,v); 51 } 52 } 53 } 54 struct T{ 55 int big,sum; 56 }tree[M<<2]; 57 void pushup(int rt){ 58 tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; 59 tree[rt].big=max(tree[rt<<1].big,tree[rt<<1|1].big); 60 } 61 void update(int x,int val,lrrt){ 62 if(L==R){ 63 tree[rt].big=tree[rt].sum=val; 64 return ; 65 } 66 imid; 67 if(mid>=x) update(x,val,lson); 68 else update(x,val,rson); 69 pushup(rt); 70 } 71 int sum(int x,int y,lrrt){ 72 if(x<=L&&R<=y) return tree[rt].sum; 73 imid; 74 int ans=0; 75 if(mid>=x) ans+=sum(x,y,lson); 76 if(mid<y) ans+=sum(x,y,rson); 77 return ans; 78 } 79 int getsum(int x,int y){ 80 int tx=top[x],ty=top[y],ans=0; 81 while(tx!=ty){ 82 if(dep[tx]<dep[ty]){ 83 swap(tx,ty); 84 swap(x,y); 85 } 86 ans+=sum(sid[tx],sid[x],iall); 87 x=fa[tx]; 88 tx=top[x]; 89 } 90 if(dep[x]>dep[y]) swap(x,y); 91 return ans+sum(sid[x],sid[y],iall); 92 } 93 int query(int x,int y,lrrt){ 94 if(x<=L&&R<=y) return tree[rt].big; 95 imid; 96 int ans=-inf; 97 if(mid>=x) ans=max(ans,query(x,y,lson)); 98 if(mid<y) ans=max(ans,query(x,y,rson)); 99 return ans; 100 } 101 int getmax(int x,int y){ 102 int tx=top[x],ty=top[y],ans=-inf; 103 while(tx!=ty){ 104 if(dep[tx]<dep[ty]){ 105 swap(tx,ty); 106 swap(x,y); 107 } 108 ans=max(ans,query(sid[tx],sid[x],iall)); 109 x=fa[tx]; 110 tx=top[x]; 111 } 112 if(dep[x]>dep[y]) swap(x,y); 113 return max(ans,query(sid[x],sid[y],iall)); 114 } 115 int main(){ 116 int m; 117 while(~scanf("%d",&m)){ 118 g.init(); 119 for(int i=0,u,v;i<m-1;i++){ 120 scanf("%d%d",&u,&v); 121 g.add(u,v); 122 g.add(v,u); 123 } 124 n=fa[1]=dep[1]=num[0]=0; 125 dfs(1); 126 get(1,1); 127 mt(tree,0); 128 for(int i=1,x;i<=m;i++){ 129 scanf("%d",&x); 130 update(sid[i],x,iall); 131 } 132 scanf("%d",&m); 133 char op[8]; 134 int x,y; 135 while(m--){ 136 scanf("%s%d%d",op,&x,&y); 137 if(op[0]=='C') update(sid[x],y,iall); 138 else if(op[1]=='M') printf("%d\n",getmax(x,y)); 139 else printf("%d\n",getsum(x,y)); 140 } 141 } 142 return 0; 143 }
Problem 2082 过路费 http://acm.fzu.edu.cn/problem.php?pid=2082
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 typedef __int64 LL; 12 const int M=50010; 13 struct IN{ 14 int u,v,w; 15 }e[M]; 16 struct G{ 17 struct E{ 18 int v,next; 19 }e[M<<1]; 20 int le,head[M]; 21 void init(){ 22 le=0; 23 mt(head,-1); 24 } 25 void add(int u,int v){ 26 e[le].v=v; 27 e[le].next=head[u]; 28 head[u]=le++; 29 } 30 }g; 31 int n,fa[M],dep[M],num[M],son[M],sid[M],top[M]; 32 void dfs(int u){ 33 num[u]=1; 34 son[u]=0; 35 for(int i=g.head[u];~i;i=g.e[i].next){ 36 int v=g.e[i].v; 37 if(v!=fa[u]){ 38 fa[v]=u; 39 dep[v]=dep[u]+1; 40 dfs(v); 41 if(num[son[u]]<num[v]) son[u]=v; 42 num[u]+=num[v]; 43 } 44 } 45 } 46 void get(int u,int Top){ 47 sid[u]=++n; 48 top[u]=Top; 49 if(son[u]) get(son[u],Top); 50 for(int i=g.head[u];~i;i=g.e[i].next){ 51 int v=g.e[i].v; 52 if(v!=fa[u]&&v!=son[u]){ 53 get(v,v); 54 } 55 } 56 } 57 LL tree[M<<2]; 58 void pushup(int rt){ 59 tree[rt]=tree[rt<<1]+tree[rt<<1|1]; 60 } 61 void update(int x,int val,lrrt){ 62 if(L==R){ 63 tree[rt]=val; 64 return ; 65 } 66 imid; 67 if(mid>=x) update(x,val,lson); 68 else update(x,val,rson); 69 pushup(rt); 70 } 71 LL query(int x,int y,lrrt){ 72 if(x<=L&&R<=y) return tree[rt]; 73 imid; 74 LL ans=0; 75 if(mid>=x) ans+=query(x,y,lson); 76 if(mid<y) ans+=query(x,y,rson); 77 return ans; 78 } 79 LL getsum(int x,int y){ 80 int tx=top[x],ty=top[y]; 81 LL ans=0; 82 while(tx!=ty){ 83 if(dep[tx]<dep[ty]){ 84 swap(tx,ty); 85 swap(x,y); 86 } 87 ans+=query(sid[tx],sid[x],iall); 88 x=fa[tx]; 89 tx=top[x]; 90 } 91 if(x==y) return ans; 92 if(dep[x]>dep[y]) swap(x,y); 93 return ans+query(sid[son[x]],sid[y],iall); 94 } 95 int main(){ 96 int m,q; 97 while(~scanf("%d%d",&m,&q)){ 98 g.init(); 99 for(int i=1;i<m;i++){ 100 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); 101 g.add(e[i].u,e[i].v); 102 g.add(e[i].v,e[i].u); 103 } 104 n=fa[1]=dep[1]=num[0]=0; 105 dfs(1); 106 get(1,1); 107 mt(tree,0); 108 for(int i=1;i<m;i++){ 109 if(dep[e[i].u]>dep[e[i].v]){ 110 swap(e[i].u,e[i].v); 111 } 112 update(sid[e[i].v],e[i].w,iall); 113 } 114 while(q--){ 115 int op,x,y; 116 scanf("%d%d%d",&op,&x,&y); 117 if(!op) update(sid[e[x].v],y,iall); 118 else printf("%I64d\n",getsum(x,y)); 119 } 120 } 121 return 0; 122 }
Housewife Wind http://poj.org/problem?id=2763
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 const int M=100010; 12 struct IN{ 13 int u,v,w; 14 }e[M]; 15 struct G{ 16 struct E{ 17 int v,next; 18 }e[M<<1]; 19 int le,head[M]; 20 void init(){ 21 le=0; 22 mt(head,-1); 23 } 24 void add(int u,int v){ 25 e[le].v=v; 26 e[le].next=head[u]; 27 head[u]=le++; 28 } 29 }g; 30 int n,fa[M],dep[M],num[M],son[M],sid[M],top[M]; 31 void dfs(int u){ 32 num[u]=1; 33 son[u]=0; 34 for(int i=g.head[u];~i;i=g.e[i].next){ 35 int v=g.e[i].v; 36 if(v!=fa[u]){ 37 fa[v]=u; 38 dep[v]=dep[u]+1; 39 dfs(v); 40 if(num[son[u]]<num[v]) son[u]=v; 41 num[u]+=num[v]; 42 } 43 } 44 } 45 void get(int u,int Top){ 46 sid[u]=++n; 47 top[u]=Top; 48 if(son[u]) get(son[u],Top); 49 for(int i=g.head[u];~i;i=g.e[i].next){ 50 int v=g.e[i].v; 51 if(v!=fa[u]&&v!=son[u]){ 52 get(v,v); 53 } 54 } 55 } 56 int tree[M<<2]; 57 void pushup(int rt){ 58 tree[rt]=tree[rt<<1]+tree[rt<<1|1]; 59 } 60 void update(int x,int val,lrrt){ 61 if(L==R){ 62 tree[rt]=val; 63 return ; 64 } 65 imid; 66 if(mid>=x) update(x,val,lson); 67 else update(x,val,rson); 68 pushup(rt); 69 } 70 int query(int x,int y,lrrt){ 71 if(x<=L&&R<=y) return tree[rt]; 72 imid; 73 int ans=0; 74 if(mid>=x) ans+=query(x,y,lson); 75 if(mid<y) ans+=query(x,y,rson); 76 return ans; 77 } 78 int getsum(int x,int y){ 79 int tx=top[x],ty=top[y],ans=0; 80 while(tx!=ty){ 81 if(dep[tx]<dep[ty]){ 82 swap(tx,ty); 83 swap(x,y); 84 } 85 ans+=query(sid[tx],sid[x],iall); 86 x=fa[tx]; 87 tx=top[x]; 88 } 89 if(x==y) return ans; 90 if(dep[x]>dep[y]) swap(x,y); 91 return ans+query(sid[son[x]],sid[y],iall); 92 } 93 int main(){ 94 int m,q,s; 95 while(~scanf("%d%d%d",&m,&q,&s)){ 96 g.init(); 97 for(int i=1;i<m;i++){ 98 scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); 99 g.add(e[i].u,e[i].v); 100 g.add(e[i].v,e[i].u); 101 } 102 n=fa[1]=dep[1]=num[0]=0; 103 dfs(1); 104 get(1,1); 105 mt(tree,0); 106 for(int i=1;i<m;i++){ 107 if(dep[e[i].u]>dep[e[i].v]){ 108 swap(e[i].u,e[i].v); 109 } 110 update(sid[e[i].v],e[i].w,iall); 111 } 112 while(q--){ 113 int op,x,y; 114 scanf("%d%d",&op,&x); 115 if(op){ 116 scanf("%d",&y); 117 update(sid[e[x].v],y,iall); 118 continue; 119 } 120 printf("%d\n",getsum(s,x)); 121 s=x; 122 } 123 } 124 return 0; 125 }
Aladdin and the Return Journey http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1348
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mt(a,b) memset(a,b,sizeof(a)) 5 #define lrrt int L,int R,int rt 6 #define iall 1,n,1 7 #define imid int mid=(L+R)>>1 8 #define lson L,mid,rt<<1 9 #define rson mid+1,R,rt<<1|1 10 using namespace std; 11 const int M=30010; 12 struct G{ 13 struct E{ 14 int v,next; 15 }e[M<<1]; 16 int le,head[M]; 17 void init(){ 18 le=0; 19 mt(head,-1); 20 } 21 void add(int u,int v){ 22 e[le].v=v; 23 e[le].next=head[u]; 24 head[u]=le++; 25 } 26 }g; 27 int val[M],n,fa[M],dep[M],num[M],son[M],sid[M],top[M]; 28 void dfs(int u){ 29 num[u]=1; 30 son[u]=0; 31 for(int i=g.head[u];~i;i=g.e[i].next){ 32 int v=g.e[i].v; 33 if(v!=fa[u]){ 34 fa[v]=u; 35 dep[v]=dep[u]+1; 36 dfs(v); 37 if(num[son[u]]<num[v]) son[u]=v; 38 num[u]+=num[v]; 39 } 40 } 41 } 42 void get(int u,int Top){ 43 sid[u]=++n; 44 top[u]=Top; 45 if(son[u]) get(son[u],Top); 46 for(int i=g.head[u];~i;i=g.e[i].next){ 47 int v=g.e[i].v; 48 if(v!=fa[u]&&v!=son[u]){ 49 get(v,v); 50 } 51 } 52 } 53 int tree[M<<2]; 54 void pushup(int rt){ 55 tree[rt]=tree[rt<<1]+tree[rt<<1|1]; 56 } 57 void update(int x,int val,lrrt){ 58 if(L==R){ 59 tree[rt]=val; 60 return ; 61 } 62 imid; 63 if(mid>=x) update(x,val,lson); 64 else update(x,val,rson); 65 pushup(rt); 66 } 67 int query(int x,int y,lrrt){ 68 if(x<=L&&R<=y) return tree[rt]; 69 imid; 70 int ans=0; 71 if(mid>=x) ans+=query(x,y,lson); 72 if(mid<y) ans+=query(x,y,rson); 73 return ans; 74 } 75 int getsum(int x,int y){ 76 int tx=top[x],ty=top[y],ans=0; 77 while(tx!=ty){ 78 if(dep[tx]<dep[ty]){ 79 swap(tx,ty); 80 swap(x,y); 81 } 82 ans+=query(sid[tx],sid[x],iall); 83 x=fa[tx]; 84 tx=top[x]; 85 } 86 if(dep[x]>dep[y]) swap(x,y); 87 return ans+query(sid[x],sid[y],iall); 88 } 89 int main(){ 90 int t,m; 91 while(~scanf("%d",&t)){ 92 int cas=1; 93 while(t--){ 94 printf("Case %d:\n",cas++); 95 scanf("%d",&m); 96 for(int i=1;i<=m;i++){ 97 scanf("%d",&val[i]); 98 } 99 g.init(); 100 for(int i=1,u,v;i<m;i++){ 101 scanf("%d%d",&u,&v); 102 g.add(u+1,v+1); 103 g.add(v+1,u+1); 104 } 105 n=fa[1]=dep[1]=num[0]=0; 106 dfs(1); 107 get(1,1); 108 mt(tree,0); 109 for(int i=1;i<=m;i++){ 110 update(sid[i],val[i],iall); 111 } 112 scanf("%d",&m); 113 while(m--){ 114 int op,x,y; 115 scanf("%d%d%d",&op,&x,&y); 116 if(op) update(sid[x+1],y,iall); 117 else printf("%d\n",getsum(x+1,y+1)); 118 } 119 } 120 } 121 return 0; 122 }
两个待补
bzoj1146 树上第k大 LCA
bzoj2243 树上颜色统计
http://quartergeek.com/summary-of-heavy-light-decomposition/
end