Recently, we have been strengthening the knowledge point depth and found that tree link splitting is not very easy to write.
Review the modification operation:
If the two points are on the same link, modify the interval directly.
If it is not on the same chain, modify the depth of the point to the top of the chain, and change this point to the father at the top of the chain, loop operation until the two points are on the same link, you can use the previous method.
I didn't use the LCA because I had been pitted before. Not only is it easy to write, but the efficiency is not satisfactory.
It is mainly about how to write something forgotten in the second case, and writing a template will remind you again.
#include<iostream>#include<cstdio>#include<cstdlib>#include<string.h>#include<math.h>#include<algorithm>#include<vector>#include<queue>using namespace std;#define MAXN 50005int n,m,q;vector<int> map[MAXN];int size[MAXN],fa[MAXN],son[MAXN],val[MAXN],tid[MAXN],_tid[MAXN],dep[MAXN],top[MAXN];int cnt;struct node{ int l,r,val;}tree[MAXN<<2];void dfs1(int s,int f,int d){ size[s]=1; fa[s]=f; dep[s]=d; int len=map[s].size(); for(int i=0;i<len;i++) { int e=map[s][i]; if(e==f)continue; dfs1(e,s,d+1); size[s]+=size[e]; if(son[s]==0) son[s]=e; else if(size[son[s]]<size[e]) son[s]=e; }}void dfs2(int s,int t){ tid[s]=++cnt; _tid[cnt]=s; top[s]=t; if(son[s]!=0) dfs2(son[s],t); int len=map[s].size(); for(int i=0;i<len;i++) { int e=map[s][i]; if(e!=fa[s] && e!=son[s]) dfs2(e,e); }}void build(int l,int r,int now){ tree[now].l=l; tree[now].r=r; tree[now].val=0; if(l==r) { tree[now].val=val[_tid[l]]; return ; } int mid=(l+r)>>1; build(l,mid,now<<1); build(mid+1,r,now<<1|1);}void down(int now){ tree[now<<1].val+=tree[now].val; tree[now<<1|1].val+=tree[now].val; tree[now].val=0;}void update(int l,int r,int now,int num){ if(l==tree[now].l && r==tree[now].r) { tree[now].val+=num; return ; } if(tree[now].val) down(now); int mid=(tree[now].l+tree[now].r)>>1; if(r<=mid) update(l,r,now<<1,num); else if(l>mid) update(l,r,now<<1|1,num); else { update(l,mid,now<<1,num); update(mid+1,r,now<<1|1,num); }}void change(int s,int e,int num){ while(top[s]!=top[e]) { if(dep[top[s]]<dep[top[e]]) swap(s,e); update(tid[top[s]],tid[s],1,num); s=fa[top[s]]; } if(dep[s]>dep[e]) swap(s,e); update(tid[s],tid[e],1,num);}int query(int l,int now){ if(tree[now].l==l && tree[now].r==l) return tree[now].val; if(tree[now].val) down(now); int mid=(tree[now].l+tree[now].r)>>1; if(l<=mid) return query(l,now<<1); else return query(l,now<<1|1);}int main(){ while(cin>>n>>m>>q) { memset(size,0,sizeof(size)); memset(fa,0,sizeof(fa)); memset(tid,0,sizeof(tid)); memset(son,0,sizeof(son)); cnt=0; for(int i=1;i<=n;i++) { scanf("%d",&val[i]); map[i].clear(); } for(int i=1;i<n;i++) { int a,b; scanf("%d%d",&a,&b); map[a].push_back(b); map[b].push_back(a); } dfs1(1,-1,1); dfs2(1,1); build(1,n,1); while(q--) { char ch[5]; int a,b,c; scanf("%s",ch); if(ch[0]=='Q') { scanf("%d",&a); printf("%d\n",query(tid[a],1)); } else { scanf("%d%d%d",&a,&b,&c); if(ch[0]=='I') change(a,b,c); else change(a,b,-c); } } }}
Hdu3966 _ tree link partitioning