On Changing Tree
#pragma GCC optimize(2) #include <bits/stdc++.h> #define lowbit(x) x&(-x) using namespace std; const int maxn = 1e6 + 108; typedef long long ll; const ll mod=1e9+7; int n,q; int fa[maxn],dfn[maxn],siz[maxn],dep[maxn]; vector<int>e[maxn]; inline int dfs(int cur){ static int tot=0; dfn[cur]=++tot; for(register int i=0;i<e[cur].size();++i){ int to=e[cur][i]; siz[cur]+=dfs(to); } //printf("debug dfn[%d] = %d\n",cur,dfn[cur]); return ++siz[cur]; } struct BIT{ ll o[maxn]; inline void init(){ memset(o,0,sizeof(o)); } inline void update(int pos,ll val){ while(pos<=n){ o[pos]=(o[pos]+val)%mod; pos+=lowbit(pos); } } inline ll query(int pos){ ll res=0; while(pos){ res=(res+o[pos])%mod; pos-=lowbit(pos); } return res%mod; } }atom1,atom2; int main() { #ifndef ONLINE_JUDGE freopen("1.txt", "r", stdin); #endif scanf("%d",&n); for(register int i=2;i<=n;++i){ scanf("%d",&fa[i]); e[fa[i]].emplace_back(i); dep[i]=dep[fa[i]]+1; } atom1.init(); atom2.init(); dfs(1); scanf("%d",&q); int type,v,x; ll k; while(q--){ scanf("%d",&type); if(type==1){ scanf("%d%d%lld",&v,&x,&k); atom1.update(dfn[v],x+dep[v]*k%mod); atom1.update(dfn[v]+siz[v],mod-(x+dep[v]*k%mod)%mod); atom2.update(dfn[v],k); atom2.update(dfn[v]+siz[v],(mod-k%mod)%mod); } else{ scanf("%d",&v); printf("%lld\n",(atom1.query(dfn[v])%mod-dep[v]*atom2.query(dfn[v])%mod+mod)%mod); } } return 0; }