zoukankan      html  css  js  c++  java
  • Bzoj 3223: Tyvj 1729 文艺平衡树(splay)

    3223: Tyvj 1729 文艺平衡树
    Time Limit: 10 Sec Memory Limit: 128 MB
    Description
    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
    Input
    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
    接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
    Output
    输出一行n个数字,表示原始序列经过m次变换后的结果
    Sample Input
    5 3
    1 3
    1 3
    1 4
    Sample Output
    4 3 2 1 5
    HINT
    N,M<=100000
    Source
    平衡树

    /*
    splay 区间翻转. 
    */
    #include<iostream>
    #include<cstdio>
    #define MAXN 100010
    #define INF 1e9
    using namespace std;
    int n,m,t1,t2,tot,root,size[MAXN],id[MAXN],s[MAXN],fa[MAXN],tree[MAXN][2],rev[MAXN];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void push(int x)
    {
        rev[tree[x][0]]^=1,rev[tree[x][1]]^=1,rev[x]^=1;
        swap(tree[x][0],tree[x][1]);
        return ;
    }
    void rotate(int x,int &k)
    {
        int y=fa[x],z=fa[y],l,r;
        if(rev[y]) push(y);
        if(rev[x]) push(x);
        if(tree[y][0]==x) l=0;else l=1;r=l^1;
        if(y==k) k=x;
        else {
            if(tree[z][0]==y) tree[z][0]=x;
            else tree[z][1]=x;
        }
        fa[y]=x,fa[x]=z,fa[tree[x][r]]=y;
        tree[y][l]=tree[x][r];tree[x][r]=y;
        size[y]=size[tree[y][0]]+size[tree[y][1]]+1;
        size[x]=size[tree[x][0]]+size[tree[x][1]]+1;
        return ;
    }
    void splay(int x,int &k)
    {
        int y,z;
        while(x!=k)
        {
            y=fa[x],z=fa[y];
            if(y!=k)
            {
                if((tree[z][0]==y)^(tree[y][0]==x)) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
        return ;
    }
    void add(int &k,int f,int x,int y)
    {
        if(!k){k=++tot;id[tot]=x;s[tot]=y;size[k]=1;fa[k]=f;splay(k,root);return ;}
        if(x<=id[k]) add(tree[k][0],k,x,y);
        else add(tree[k][1],k,x,y);
        return ;
    }
    int query(int x,int k)
    {
        if(rev[k]) push(k);
        if(size[tree[k][0]]+1==x) return k;
        if(x>size[tree[k][0]]) return query(x-size[tree[k][0]]-1,tree[k][1]);
        else return query(x,tree[k][0]);
    }
    void slove(int x,int y)
    {
        t1=query(x-1+1,root),t2=query(y+1+1,root);
        splay(t1,root),splay(t2,tree[t1][1]);
        rev[tree[t2][0]]^=1;return ;
    }
    int main()
    {
        int x,y;
        n=read(),m=read();
        add(root,root,0,-INF),add(root,root,n+2,INF);
        for(int i=2;i<=n+1;i++) add(root,root,i,i-1);
        while(m--)
        {
            x=read(),y=read();
            slove(x,y);
        }
        for(int i=1;i<=n;i++) printf("%d ",s[query(i+1,root)]);
        return 0;
    }
  • 相关阅读:
    阿里fastjson工具类
    poi导出excel2007版本
    java 利用poi 实现excel合并单元格后出现边框有的消失的解决方法
    spring整合atomikos实现分布式事务
    彻底理解ThreadLocal
    kubernetes架构和组件
    Promethues实战-简易教程系列
    Celery
    对称加密,非对称加密,证书机制
    Git diff
  • 原文地址:https://www.cnblogs.com/nancheng58/p/10068081.html
Copyright © 2011-2022 走看看