• 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
    ",bouns[q[i].id]+sum(pos[q[i].id].st)*mul[q[i].id]);
            }
        }
    }
    View Code
  • 相关阅读:
    代码之美
    一点对互联网的浅薄理解
    angularjs填写表单
    一种通用数据采集的schema定义形式
    maven常用命令
    find which process occupy the PORT
    Mac上安装boost开放环境
    codeforces 581B Luxurious Houses
    codeforces 599A Patrick and Shopping
    codeforces 597A Divisibility
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12571191.html
Copyright © 2020-2023  润新知