UCF Local Programming Contest 2018 E题(树状数组+dfs序)

如果这道题没有一个限制,那么就是一道树状数组+dfs序的裸题

第一个请求或许会带来困惑,导致想要动态建树,如果真的动态修改树,那么dfs序必定会改变,很难维护,并且数据很大,暴力应该会T

所以不妨先把全部的节点建好,这样只需要求一次dfs序,而对于第一种操作

我们只需要再那个位置减去在他之前的dfs序的bouns求和,并在这个的后一个位置+回来,这样就有这个点被修改,并且成为了一个新点,等同于要求的操作

#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

 

posted @ 2020-03-25 22:41  朝暮不思  阅读(227)  评论(0编辑  收藏  举报