题解:
似乎是树链剖分的题目,但是被我用树状数组解决了。。。
代码:
#include<bits/stdc++.h> typedef long long ll; const int N=1000010; int tot,n,m,i,v[N],dp,p[N],pre[N],tt[N],L[N],R[N],a,b,T; ll c[N][3],dis[N]; void cc(int x,ll w,int typ){for (;x<=tot;x+=x&-x)c[x][typ]+=w;} ll sum(int x,int typ){ll ans=0;for (;x;x-=x&-x)ans+=c[x][typ];return ans;} void link(int x,int y){dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;} void dfs(int x,int fa) { tot++;L[x]=tot; for (int i=p[x];i;i=pre[i]) if (tt[i]!=fa) { dis[tt[i]]=dis[x]+1; dfs(tt[i],x); } tot++;R[x]=tot; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++)scanf("%d",&v[i]); for (int i=1;i<n;i++)scanf("%d%d",&a,&b),link(a,b),link(b,a); dfs(1,0); for (int i=1;i<=n;i++)cc(L[i],v[i],0),cc(R[i],-v[i],0); for (int i=1;i<=m;i++) { scanf("%d",&T); if (T==1) { scanf("%d%d",&a,&b); cc(L[a],b,0);cc(R[a],-b,0); } else if (T==2) { scanf("%d%d",&a,&b); cc(L[a],b,1);cc(R[a],-b,1); cc(L[a],dis[a]*(ll)b,2); cc(R[a],-dis[a]*(ll)b,2); } else { scanf("%d",&a); printf("%lld\n",sum(L[a],0)-sum(L[a],2)+sum(L[a],1)*(dis[a]+1)); } } }