zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    css word-wrap与word-break区别
    input输入框光标位置问题
    正则表达式(二)- 位置匹配攻略
    正则表达式(一)- 字符匹配攻略
    mac电脑重启nginx报错nginx: [error] invalid PID number "" in "/usr/local/var/run/nginx.pid"
    指定js文件不使用 eslint 语法检查
    管理github/gitlab生成多个ssh key
    前端切图两种方法整理
    梳理:移动端Viewport的知识
    切图 — Photoshop(转载)
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12571191.html
Copyright © 2011-2022 走看看