zoukankan      html  css  js  c++  java
  • BZOJ 1251 序列终结者(Splay)

    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1251

    【题目大意】

      给出全零序列,要求维护三个操作,区间加法,区间翻转和区间求最小值。

    【题解】

      splay基础练习。

    【代码】

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N=50010;
    int n,m,a[N],val[N],mn[N],tag[N],size[N];
    int son[N][2],f[N],tot,root;bool rev[N];
    void rev1(int x){if(!x)return;swap(son[x][0],son[x][1]);rev[x]^=1;}
    void add1(int x,int p){if(!x)return;val[x]+=p;mn[x]+=p;tag[x]+=p;}
    void pb(int x){
        if(rev[x]){
            rev1(son[x][0]);
            rev1(son[x][1]);
            rev[x]=0;
        }
        if(tag[x]){
            add1(son[x][0],tag[x]);
            add1(son[x][1],tag[x]);
            tag[x]=0;
        }
    }
    void up(int x){
        size[x]=1,mn[x]=val[x];
        if(son[x][0]){
            size[x]+=size[son[x][0]];
            if(mn[x]<mn[son[x][0]])mn[x]=mn[son[x][0]];
        }
        if(son[x][1]){
            size[x]+=size[son[x][1]];
            if(mn[x]<mn[son[x][1]])mn[x]=mn[son[x][1]];
        }
    }
    void rotate(int x){
        int y=f[x],w=son[y][1]==x;
        son[y][w]=son[x][w^1];
        if(son[x][w^1])f[son[x][w^1]]=y;
        if(f[y]){
            int z=f[y];
            if(son[z][0]==y)son[z][0]=x;
            if(son[z][1]==y)son[z][1]=x;
        }f[x]=f[y];son[x][w^1]=y;f[y]=x;up(y);
    }
    void splay(int x,int w){
        int s=1,i=x,y;a[1]=x;
        while(f[i])a[++s]=i=f[i];
        while(s)pb(a[s--]);
        while(f[x]!=w){
            y=f[x];
            if(f[y]!=w){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
            rotate(x);
        }if(!w)root=x;
        up(x);
    }
    int build(int l,int r,int fa){
        int x=++tot,mid=(l+r)>>1;
        f[x]=fa;val[x]=a[mid];
        if(l<mid)son[x][0]=build(l,mid-1,x);
        if(r>mid)son[x][1]=build(mid+1,r,x);
        up(x);
        return x;
    }
    int kth(int k){
        int x=root,tmp;
        while(1){
            pb(x);
            tmp=size[son[x][0]]+1;
            if(k==tmp)return x;
            if(k<tmp)x=son[x][0];else k-=tmp,x=son[x][1];
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)a[i]=0;
        root=build(0,n+1,0);
        while(m--){
            int op,x,y,z;
            scanf("%d",&op);
            if(op==1){
                scanf("%d%d%d",&x,&y,&z);
                x=kth(x),y=kth(y+2);
                splay(x,0),splay(y,x),add1(son[y][0],z);
            }else if(op==2){
                scanf("%d%d",&x,&y);
                x=kth(x),y=kth(y+2);
                splay(x,0),splay(y,x),rev1(son[y][0]);
            }else{
                scanf("%d%d",&x,&y);
                x=kth(x),y=kth(y+2);
                splay(x,0),splay(y,x),printf("%d
    ",mn[son[y][0]]);
            }
        }return 0;
    }
  • 相关阅读:
    树莓派基于scratch2控制GPIO
    一次修复linux的efi引导的集中方法总结记录
    linux(deepin) 下隐藏firefox标题栏
    log4j 1.2 配置和使用简述
    在非gnome系桌面环境下运行deepin-wine tim的错误解决
    manjaro AwesomeWM 上使用双显示器
    linux 关闭主板上的蜂鸣器声音
    anki的使用以及anki server的配置
    阅读《人类简史》-- 1.认知革命
    java生成zip包兼容Linux
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj1251.html
Copyright © 2011-2022 走看看