suoi22 WRX知识树(dfs序)
把一条路径拆成到根的四个链(两端点、lca和fa[lca]),然后给dfs序中链的端点做单点修改、区间查询它的子树和再加上它原来的权值就可以了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=1e6+10; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 int N,M; 22 int eg[maxn*2][2],egh[maxn],ect; 23 int v[maxn],fa[maxn],bfa[maxn]; 24 int lq[maxn*2][2],lqh[maxn],lca[maxn][2]; 25 int dfn[maxn][2],tot; 26 int stk[maxn][2],sh; 27 ll tr[maxn]; 28 int que[maxn]; 29 bool vis[maxn]; 30 31 inline void adeg(int a,int b){ 32 eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect; 33 } 34 35 int getf(int x){return x==bfa[x]?x:bfa[x]=getf(bfa[x]);} 36 37 inline void add(int x,ll y){ 38 for(;x>0&&x<=N;x+=lowb(x)) tr[x]+=y; 39 } 40 inline ll query(int x){ 41 ll re=0;for(;x>0;x-=lowb(x)) re+=tr[x];return re; 42 } 43 44 void dfs(){ 45 stk[sh=1][0]=1;stk[1][1]=egh[1]; 46 dfn[1][0]=tot=1; 47 while(sh){ 48 int x=stk[sh][0],i=stk[sh][1],b=eg[i][0]; 49 vis[x]=1; 50 if(!i){ 51 for(int j=lqh[x];j;j=lq[j][1]){ 52 int c=lq[j][0]; 53 if(vis[c]) lca[j>>1][0]=getf(c); 54 } 55 bfa[getf(x)]=fa[x]; 56 dfn[x][1]=tot; 57 sh--;continue; 58 } 59 stk[sh][1]=eg[i][1]; 60 if(!vis[b]){ 61 fa[b]=x;stk[++sh][0]=b,stk[sh][1]=egh[b]; 62 dfn[b][0]=++tot; 63 } 64 65 } 66 } 67 68 int main(){ 69 //freopen(".in","r",stdin); 70 rei i; 71 N=rd(),M=rd(); 72 for(i=1;i<=N;i++) v[i]=rd(); 73 for(i=1;i<N;i++){ 74 int a=rd(),b=rd(); 75 adeg(a,b);adeg(b,a); 76 }for(i=1;i<=N;i++) bfa[i]=i; 77 for(i=1;i<=M;i++){ 78 int a=rd(),b=rd(); 79 if(!a){ 80 que[i]=b; 81 }else{ 82 int c=rd(),d=rd(); 83 lca[i][1]=d; 84 lq[i<<1][0]=b;lq[i<<1][1]=lqh[c];lqh[c]=i<<1; 85 lq[i<<1|1][0]=c;lq[i<<1|1][1]=lqh[b];lqh[b]=i<<1|1; 86 } 87 } 88 dfs(); 89 for(i=1;i<=M;i++){ 90 if(lca[i][0]){ 91 // printf("!%d %d %d\n",lca[i][0],lq[i<<1][0],lq[i<<1|1][0]); 92 add(dfn[lca[i][0]][0],-lca[i][1]); 93 if(fa[lca[i][0]]) add(dfn[fa[lca[i][0]]][0],-lca[i][1]); 94 add(dfn[lq[i<<1][0]][0],lca[i][1]); 95 add(dfn[lq[i<<1|1][0]][0],lca[i][1]); 96 // cout<<"mmm"<<endl; 97 }else{ 98 printf("%lld\n",v[que[i]]+query(dfn[que[i]][1])-query(dfn[que[i]][0]-1)); 99 } 100 101 } 102 return 0; 103 }