解法:
先DFS给每个节点一个id,然后可以获得每个节点这颗子树的区间(一定是连续的),这样就可以进行线段树的操作(单点修改,区间修改,和区间查询),
#define LL long long const int maxn=50005; const int mod=1000000007; class Solution { public: int cnt; int N; LL sum[maxn<<2], lazy[maxn<<2]; int in[maxn],out[maxn]; vector<int> adj[maxn]; void update_range(int tleft, int tright, int left, int right, int idx, int val){ if(tleft>right || tright<left) return; if(tleft<=left && tright>=right){ sum[idx]=(sum[idx]+val*(right-left+1)%mod)%mod; lazy[idx]=(lazy[idx]+val)%mod; return; } push_down(idx,left,right); int mid=(left+right)>>1; update_range(tleft,tright,left,mid,idx*2,val); update_range(tleft,tright,mid+1,right,idx*2+1,val); sum[idx]=(sum[idx*2]+sum[idx*2+1])%mod; } void update_single(int targetidx, int left, int right, int idx, int val){ if(left>targetidx || right<targetidx) return; if(left==right) { sum[idx]+=val; sum[idx]%=mod; return; } push_down(idx,left,right); int mid=(left+right)/2; update_single(targetidx,left,mid,idx*2,val); update_single(targetidx,mid+1,right,idx*2+1,val); sum[idx]=(sum[idx*2]+sum[idx*2+1])%mod; } void push_down(int idx, int left, int right){ int mid=(left+right)/2; sum[idx*2]=(sum[idx*2]+lazy[idx]*(mid-left+1)%mod)%mod; sum[idx*2+1]=(sum[idx*2+1]+lazy[idx]*(right-(mid+1)+1)%mod)%mod; lazy[idx*2]=(lazy[idx*2]+lazy[idx])%mod; lazy[idx*2+1]=(lazy[idx*2+1]+lazy[idx])%mod; lazy[idx]=0; } LL query(int qleft, int qright, int left, int right, int idx){ if(qleft>right || qright<left) return 0; if(qleft<=left && qright>=right){ return sum[idx]; } push_down(idx,left,right); LL res=0; int mid=(left+right)>>1; LL l=query(qleft,qright,left,mid,idx*2); LL r=query(qleft,qright,mid+1,right,idx*2+1); res=(l+r)%mod; return res; } vector<int> bonus(int n, vector<vector<int>>& leadership, vector<vector<int>>& operations) { N=n; cnt=0; for(auto l:leadership){ adj[l[0]].push_back(l[1]); } dfs(1); vector<int> res; for(auto ope:operations){ if(ope[0]==1){ update_single(in[ope[1]],1,cnt,1,ope[2]); }else if(ope[0]==2){ update_range(in[ope[1]],out[ope[1]],1,cnt,1,ope[2]); }else { LL ret=query(in[ope[1]],out[ope[1]],1,cnt,1); ret%=mod; res.push_back(ret); } } return res; } void dfs(int u){ in[u]=++cnt; for(int c:adj[u]){ dfs(c); } out[u]=cnt; } };