zoukankan      html  css  js  c++  java
  • bzoj3223 文艺平衡树 codevs3303 翻转区间

    splay模版题吧 只有区间翻转
    至于为什么要把须翻转区间旋到根 因为查找一个区间可以先找出他左端点左边第一个点和右端点x右边第一个点y 然后将x旋到根节点 y旋到x的右儿子 这样x的右边的点就是所有大于x的点而y的左边是所有小于y的点 这样刚好包涵了所需要翻转的区间
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=100005;
    int n,m,root;
    int c[M][2],fa[M],size[M];
    bool rev[M];
    void pushup(int k){int l=c[k][0],r=c[k][1]; size[k]=size[l]+size[r]+1;}
    void pushdown(int k){
        int l=c[k][0],r=c[k][1];
        if(rev[k]){
            swap(c[k][0],c[k][1]);
            rev[l]^=1; rev[r]^=1; rev[k]=0;
        }
    }
    void build(int l,int r,int f){
        if(l>r) return ;
        if(l==r){
            fa[l]=f; size[l]=1;
            if(l<f) c[f][0]=l;
            else c[f][1]=l;
            return ;
        }
        int mid=(l+r)>>1;
        build(l,mid-1,mid); build(mid+1,r,mid);
        fa[mid]=f; pushup(mid);
        if(mid<f) c[f][0]=mid;
        else c[f][1]=mid;
    }
    void rotate(int x,int& k){
        int y=fa[x],z=fa[y],l=1,r;
        if(c[y][0]==x) l=0; r=l^1;
        if(y==k) k=x;
        else{if(c[z][0]==y) c[z][0]=x; else c[z][1]=x;}
        fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
        c[y][l]=c[x][r]; c[x][r]=y;
        pushup(x); pushup(y);
    }
    void splay(int x,int& k){
        while(x!=k){
            int y=fa[x],z=fa[y];
            if(y!=k){
                if(c[y][0]==x^c[z][0]==y) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    int find(int x,int rank){
        pushdown(x);
        int l=c[x][0],r=c[x][1];
        if(size[l]+1==rank) return x;
        else if(size[l]>=rank) return find(l,rank);
        else return find(r,rank-size[l]-1);
    }
    void rever(int l,int r){
        int x=find(root,l),y=find(root,r+2);
        splay(x,root); splay(y,c[root][1]);
        rev[c[y][0]]^=1;
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        build(1,n+2,0); root=(n+3)>>1;
        while(m--){
            int l,r; scanf("%d %d",&l,&r);
            rever(l,r);
        }
        for(int i=2;i<=n+1;i++) printf("%d ",find(root,i)-1);
        return 0;
    }
    View Code
  • 相关阅读:
    JSP中 == 和equals的区别
    使用Cookie保存用户名密码,再次登陆时将Cookie用户名密码取出来并直接放置到用户名密码文本框中
    学习Java Web开发中遇到的问题,及其解决方法
    部署、测试、服务工作的经验记录
    Python基础--dict字典操作
    Python基础--dict字典
    Python基础--预留空 5
    Python基础--预留空 4
    Python基础--tuple 元组
    Python基础--预留3
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/6910154.html
Copyright © 2011-2022 走看看