题意
q次操作,操作有两种:
1 v x k:a[v]+=x,a[v’]+=x-k(v’是v的子节点)…
2 v:查询
Sample Input
1
3
1 1
3
1 1 2 1
2 1
2 2
Sample Output
2
1
这个地方的思路应该是一种套路。多学学。。
可以参考https://vjudge.net/solution/10068685的。。
我的代码不知道什么地方错了。re。。。
int fst[N],vv[N<<1],nxt[N<<1],tot;
int dep[N];
LL xval[N<<2],kval[N<<2];
int n;
int sid[N],tid[N];
void add(int u,int v){
vv[tot]=v;nxt[tot]=fst[u];fst[u]=tot++;
}
void dfs(int u,int fa){
sid[u]=++cnt;
for(int i=fst[u];~i;i=nxt[i]){
int v=vv[i];
if(v==fa)continue;
dep[v]=dep[u]+1;
dfs(v,u);
}
tid[u]=cnt;
}
inline int lowbit(int x){return x&(-x);}
void upx(int x,LL val){
while(x<=n){
xval[x]=(xval[x]+val)%mod;
x+=lowbit(x);
}
}
void upk(int x,LL val){
while(x<=n){
kval[x]=(kval[x]+val)%mod;
x+=lowbit(x);
}
}
LL qx(int x){
LL ret=0;
while(x){ ret=(ret+xval[x])%mod; x-=lowbit(x); }
return ret;
}
LL qk(int x){
LL ret=0;
while(x){ ret=(ret+kval[x])%mod; x-=lowbit(x); }
return ret;
}
int main(){
int T;sf("%d",&T);
while(T--){
mem(dep,0);mem(fst,-1);tot=0;mem(kval,0);mem(kval,0);cnt=0;
sf("%d",&n);
rep(i,2,n){ int x;sf("%d",&x);add(i,x);add(x,i); }
dep[1]=0;
dfs(1,1);
int q;sf("%d",&q);
while(q--){
LL op,v,x,k;sf("%lld",&op);
if(op==1){
sf("%lld%lld%lld",&v,&x,&k);
upk(sid[v],k); upx(sid[v],(x+(k*dep[v])%mod)%mod);
upk(tid[v]+1,-k);upx(tid[v]+1,-(x+(x*dep[v])%mod)%mod);
}
else{
sf("%lld",&v);
LL x=qx(sid[v]);
LL k=qk(sid[v]);
pf("%lld\n",(x-k*dep[v]%mod+mod)%mod);
}
}
}
}