NC23051 华华和月月种树(离线+树状数组)
这题动态的难做,因此考虑静态转化,先建成完全的树
之后直接维护,当我们新加入这个点的时候,把这个点的之前权值记录下来
因为这个时候才会被操作影响
#include<bits/stdc++.h> typedef long long ll; using namespace std; typedef pair<int,int> pll; const int N=1e6+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; int cnt,a[N],b[N],opt[N],l[N],r[N],idx; ll tr[N],ans[N]; vector<int> g[N]; int lowbit(int x){ return x&-x; } void add(int x,int c){ int i; for(i=x;i<N;i+=lowbit(i)){ tr[i]+=c; } } ll sum(int x){ ll res=0; for(int i=x;i;i-=lowbit(i)){ res+=tr[i]; } return res; } void dfs(int u){ l[u]=++idx; for(auto x:g[u]) dfs(x); r[u]=idx; } int main(){ ios::sync_with_stdio(false); int m; cin>>m; int i; for(i=1;i<=m;i++){ cin>>opt[i]>>a[i]; if(opt[i]==1){ g[a[i]].push_back(++cnt); b[i]=cnt; } else if(opt[i]==2){ cin>>b[i]; } } dfs(0); for(i=1;i<=m;i++){ if(opt[i]==1){ ans[l[b[i]]]-=sum(l[a[i]]); } else if(opt[i]==2){ add(l[a[i]],b[i]); add(r[a[i]]+1,-b[i]); } else{ cout<<ans[l[a[i]]]+sum(l[a[i]])<<endl; } } return 0; }
没有人不辛苦,只有人不喊疼