Given a rooted tree ( the root is node 1 ) of N nodes. Initially, each node has zero point.
Then, you need to handle Q operations. There're two types:
1 L X: Increase points by X of all nodes whose depth equals L ( the depth of the root is zero ). (x≤108)
2 X: Output sum of all points in the subtree whose root is X.
Input
Just one case.
The first lines contain two integer, N,Q(N≤105,Q≤105).
The next n−1 lines: Each line has two integer aaa,bbb, means that node aaa is the father of node b. It's guaranteed that the input data forms a rooted tree and node 1 is the root of it.
The next Q lines are queries.
Output
For each query 2, you should output a number means answer.
样例输入
3 3
1 2
2 3
1 1 1
2 1
2 3
样例输出
1
0
题意
给你一颗以1为根节点的数,有两个操作
1.层数为L的节点增加X
2.查询以X为根节点的子树总权和
题解
操作2很容易想到dfs维护树状数组
对于操作1,可以把层数按sqrt(n)分块,对于层数点数<=block的直接暴力更新,对于>block先保存进数组ans,查询的时候二分左右区间可以知道根的节点数,再乘ans,这样可以把单次操作的复杂度固定在sqrt(n)范围内
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 #define LL long long 5 6 const int maxn=1e5+5; 7 int s[maxn],e[maxn],tot,n; 8 LL sum[maxn],ans[maxn]; 9 vector<int>G[maxn],deep[maxn],q; 10 void dfs(int u,int fa,int d) 11 { 12 s[u]=++tot; 13 deep[d].push_back(s[u]); 14 for(auto v:G[u]) 15 { 16 if(v==fa)continue; 17 dfs(v,u,d+1); 18 } 19 e[u]=tot; 20 } 21 int lowbit(int x) 22 { 23 return x&(-x); 24 } 25 void update(int x,int add) 26 { 27 for(int i=x;i<=n;i+=lowbit(i)) 28 sum[i]+=add; 29 } 30 LL query(int x) 31 { 32 LL ans=0; 33 for(int i=x;i>0;i-=lowbit(i)) 34 ans+=sum[i]; 35 return ans; 36 } 37 int main() 38 { 39 int Q,op,L,x,u,v; 40 scanf("%d%d",&n,&Q); 41 int block=sqrt(n); 42 for(int i=1;i<n;i++) 43 { 44 scanf("%d%d",&u,&v); 45 G[u].push_back(v); 46 G[v].push_back(u); 47 } 48 dfs(1,-1,0); 49 for(int i=0;i<n;i++) 50 if(deep[i].size()>block)q.push_back(i); 51 for(int i=0;i<Q;i++) 52 { 53 scanf("%d",&op); 54 if(op==1) 55 { 56 scanf("%d%d",&L,&x); 57 if(deep[L].size()>block)ans[L]+=x; 58 else 59 { 60 for(auto X:deep[L]) 61 update(X,x); 62 } 63 } 64 else 65 { 66 scanf("%d",&x); 67 LL res=query(e[x])-query(s[x]-1); 68 for(auto pos:q) 69 res+=ans[pos]*(upper_bound(deep[pos].begin(),deep[pos].end(),e[x])-lower_bound(deep[pos].begin(),deep[pos].end(),s[x])); 70 printf("%lld ",res); 71 } 72 } 73 return 0; 74 }