UCF Local Programming Contest 2018 E title (Fenwick tree + dfs order)

If this question is not a limit, then it is a tree-like array + dfs bare title sequence

The first request might be confusing, resulting in the desired dynamic contribution, if it dynamically modify the tree, then dfs sequence will certainly change, difficult to maintain, and the data is large, the violence should be T

Therefore, all of the nodes wish to completed first, so that only required once dfs sequence, and for the first operation

We just need that position minus the sum bouns dfs order before him, and in a position to come back to this after +, so there is this point to be modified, and became a new point, equivalent to the requirements of the operation

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const int inf=0x3f3f3f3f;
ll tr[N];
ll mul[N];
ll bouns[N];
int idx;
int times;
int h[N],e[N],ne[N],cnt=1;
struct node{
    int type;
    int id;
    int v;
}q[N];
struct q{
    int st;
    int ed;
}pos[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u){
    pos[u].st=++times;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        dfs(j);
    }
    pos[u].ed=times;
}
int lowbit(int x){
    return x&-x;
}
void add1(int x,ll c){
    int i;
    for(i=x;i<=cnt;i+=lowbit(i)){
        tr[i]+=c;
    }
}
ll sum(int x){
    int i;
    ll res=0;
    for(i=x;i;i-=lowbit(i)){
        res+=tr[i];
    }
    return res;
}
int main(){
    int i;
    int m,s;
    cin>>m>>s;
    memset(h,-1,sizeof h);
    for(i=1;i<=m;i++){
        scanf("%d",&q[i].type);
        scanf("%d",&q[i].id);
        if(q[i].type==1){
            cnt++;
            add(q[i].id,cnt);
            q[i].v=cnt;
        }
        else if(q[i].type==2||q[i].type==3){
            scanf("%d",&q[i].v);
        }
    }
    for(i=1;i<=cnt;i++)
        mul[i]=s;
    dfs(1);
    for(i=1;i<=m;i++){
        if(q[i].type==1){
            ll tmp=sum(pos[q[i].v].st);
            add1(pos[q[i].v].st,-tmp);
            add1(pos[q[i].v].st+1,tmp);
        }
        else if(q[i].type==2){
            ll tmp=sum(pos[q[i].id].st);
            bouns[q[i].id]+=tmp*mul[q[i].id];
            mul[q[i].id]=(ll)q[i].v;
            add1(pos[q[i].id].st,-tmp);
            add1(pos[q[i].id].st+1,tmp);
        }
        else if(q[i].type==3){
            int place1=pos[q[i].id].st;
            int place2=pos[q[i].id].ed;
            add1(place1,q[i].v);
            add1(place2+1,-q[i].v);
        }
        else{
           printf("%lld\n",bouns[q[i].id]+sum(pos[q[i].id].st)*mul[q[i].id]);
        }
    }
}
View Code

 

Guess you like

Origin www.cnblogs.com/ctyakwf/p/12571191.html