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;
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/14527006.html