【树上前缀和】
【树上前缀和】
Compare Tree Weights
【树链剖分+树状数组维护顶点前缀和】
https://atcoder.jp/contests/abc406/tasks/abc406_f
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const int N=3e5+10;
/*注意这题的下标索引*/
struct FenwickTree {
vector<int> tree;
int size;
FenwickTree(int n){
size=n;
tree.resize(n+1,0);
}
void update(int pos, int delta){
pos++;//转成1-based索引
for(;pos<=size;pos+=pos&-pos)
tree[pos]+=delta;
}
int query(int pos){
pos++;//转成1-based索引
int res=0;
for(;pos>0;pos-=pos&-pos)
res+=tree[pos];
return res;
}
int rangeQuery(int l, int r){
return query(r)-query(l-1);
}
};
int n;
int u[N],v[N];
vector<int> g[N];
//dfs序
int l_idx[N],r_idx[N];
//求dfs序:从1开始
int cur=0;
void dfs(int u){
l_idx[u]=cur;
cur++;
for(auto son:g[u]) if(l_idx[son]==-1) dfs(son);
r_idx[u]=cur;
return;
}
void solve(){
cin>>n;
FenwickTree fw(n);
for(int i=1;i<n;i++){
cin>>u[i]>>v[i];
u[i]--;v[i]--;
g[u[i]].push_back(v[i]);
g[v[i]].push_back(u[i]);
}
memset(l_idx,-1,sizeof(l_idx));
memset(r_idx,-1,sizeof(r_idx));
dfs(0);
/*
for(int i=0;i<n;i++){
cout<<l_idx[i]<<" "<<r_idx[i]<<endl;
}
*/
for(int i=0;i<n;i++){
fw.update(i,1);
}
/*
for(int i=1;i<=n;i++){
cout<<fw.query(i)<<endl;
}
*/
int sum=n;//当前总和
int q;
cin>>q;
while(q--){
int op;
cin>>op;
if(op==1){
int x,w;
cin>>x>>w;
x--;
fw.update(l_idx[x],w);
sum+=w;
}
else if(op==2){
int y;
cin>>y;
//找儿子:dfs l_idx大的那一个
int son=u[y];
if(l_idx[u[y]]<l_idx[v[y]]) son=v[y];
else son=u[y];
int ans=abs(2*fw.rangeQuery(l_idx[son],r_idx[son]-1)-sum);
cout<<ans<<endl;
}
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号