zoukankan      html  css  js  c++  java
  • bzoj 3223: Tyvj 1729 文艺平衡树

    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

     
     
     
    头一回写SPLAY的翻转……不用考虑优先级什么的,翻[l,r]的时候就把l-1和r+1挪出来,中间那串就交换左右儿子就行了(其实位置就是key)
     
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    int n,m,l,r,p,ch;
    inline int read(){
        p=0;ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') p=p*10+ch-48,ch=getchar();
        return p;
    }
    struct tree{
        int l,r,k,f,s;
        bool bo;
        tree(){
            bo=f=l=r=0;
        }
    };
    struct splay_tree{
        int size,root;
        tree t[100001];
        splay_tree(){
            size=0;root=0;
        }
        inline void ler(int &p){
            int k=t[p].r;
            t[k].f=t[p].f;
            t[p].f=k;
            t[t[k].l].f=p;
            t[p].r=t[k].l;
            t[k].l=p;
            t[k].s=t[p].s;
            t[p].s=t[t[p].l].s+t[t[p].r].s+1;
            p=k;
        }
        inline void rir(int &p){
            int k=t[p].l;
            t[k].f=t[p].f;
            t[p].f=k;
            t[t[k].r].f=p;
            t[p].l=t[k].r;
            t[k].r=p;
            t[k].s=t[p].s;
            t[p].s=t[t[p].l].s+t[t[p].r].s+1;
            p=k;
        }
        inline void ph(int &x,bool bo){
            if (bo) rir(x);else ler(x);
        }
        inline bool getc(int x){
            return t[t[x].f].l==x;
        }
        inline void rot(int l){
            if (t[l].f==root) ph(root,getc(l));else
            if (getc(t[l].f)) ph(t[t[t[l].f].f].l,getc(l));else ph(t[t[t[l].f].f].r,getc(l));
        }
        inline void splay(int l,int f){
            while (t[l].f!=f){
                if (t[t[l].f].f==f) rot(l);else
                if (getc(l)==getc(t[l].f)) rot(t[l].f),rot(l);else rot(l),rot(l);
            }
        }
        inline void build(int &p,int l,int r){
            if (l>r) return;
            p=++size;
            int mid=(l+r)>>1;
            t[p].k=mid;
            build(t[p].l,l,mid-1);
            build(t[p].r,mid+1,r);
            t[t[p].l].f=t[t[p].r].f=p;
            t[p].s=1+t[t[p].l].s+t[t[p].r].s;
        }
        inline void pd(int x){
            if (t[x].bo){
                t[t[x].l].bo^=1;t[t[x].r].bo^=1;
                t[x].bo=0;
                swap(t[x].l,t[x].r);
            }
        }
        inline int find(int x,int y){
            pd(x);
            if (t[t[x].l].s<y-1) return find(t[x].r,y-1-t[t[x].l].s);
            if (t[t[x].l].s==y-1) return x;
            return find(t[x].l,y);
        }
        inline void dfs(int x){
            if (!x) return;
            pd(x);
            dfs(t[x].l);if (t[x].k!=0&&t[x].k<=n)printf("%d ",t[x].k);dfs(t[x].r);
        }
    };
    splay_tree t;
    int main(){
        n=read();m=read();
        t.build(t.root,0,n+1);
        while(m--){
            l=read();r=read();
            l=t.find(t.root,l);r=t.find(t.root,r+2);
            t.splay(l,0);t.splay(r,l);
            t.t[t.t[r].l].bo^=1;
        }
        t.dfs(t.root);
    }
     
  • 相关阅读:
    到底什么时候该使用MQ?
    阿里巴巴开源项目 Druid 负责人温少访谈
    MYSQL外键的使用以及优缺点
    SpringMVC拦截器(资源和权限管理)
    SpringMVC访问静态资源
    设计模式读书笔记文档下载
    java提高篇(八)----详解内部类
    Storm:最火的流式处理框架
    vue 学习视频推荐 & 初始化项目流程
    页面布局练习
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5220287.html
Copyright © 2011-2022 走看看