zoukankan      html  css  js  c++  java
  • Tyvj:1729 文艺平衡树(saply练习)

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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

    没什么可以说的,蓝桥杯求稳,多写点。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=100010;
    int N;
    void swap(int &x,int &y){
        int tmp=x; x=y;y=tmp;
    }
    struct Splay
    {
        int ch[maxn][2],fa[maxn],key[maxn],sz[maxn],lazy[maxn],rt,cnt;
        Splay(){
            rt=cnt=0;
        }
        int get(int x) { return ch[fa[x]][1]==x; }
        void pushdown(int Now){
            if(lazy[Now]){
                swap(ch[Now][0],ch[Now][1]);
                if(ch[Now][0]) lazy[ch[Now][0]]^=1;
                if(ch[Now][1]) lazy[ch[Now][1]]^=1;
                lazy[Now]=0;
            }
        }
        void pushup(int Now){
            sz[Now]=1+sz[ch[Now][0]]+sz[ch[Now][1]];
        }
        int build(int L,int R,int f)
        {
            if(L>R) return 0;
            int Mid=(L+R)>>1;    
            if(!rt) rt=Mid;
            key[Mid]=Mid; fa[Mid]=f; lazy[Mid]=0;
            ch[Mid][0]=build(L,Mid-1,Mid); 
            ch[Mid][1]=build(Mid+1,R,Mid);
            pushup(Mid);
            return Mid;
        }
        int find(int x)
        {
            int Now=rt;
            while(true){
                pushdown(Now);
                if(sz[ch[Now][0]]>=x) Now=ch[Now][0];
                else {
                    x=x-sz[ch[Now][0]]-1;
                    if(x==0) return Now;
                    Now=ch[Now][1];
                }
            }
        }
        void rotate(int x)
        {
            int old=fa[x],fold=fa[old],opt=get(x);
            pushdown(old); pushdown(x);
            ch[old][opt]=ch[x][opt^1]; fa[ch[x][opt^1]]=old;
            ch[x][opt^1]=old; fa[old]=x; fa[x]=fold;
            pushup(old); pushup(x);
            if(fold) ch[fold][ch[fold][1]==old]=x;
        }
        void splay(int x,int y)
        {
            for(int f;(f=fa[x])!=y;rotate(x))
              if(fa[f]!=y) 
               rotate(get(f)==get(x)?f:x);
            if(!y) rt=x;
        }
        void revers(int x,int y)
        {
            x=find(x); splay(x,0);
            y=find(y); splay(y,x);
            lazy[ch[ch[rt][1]][0]]^=1;
        }
        void print(int Now)
        {
            pushdown(Now);
            if(ch[Now][0]) print(ch[Now][0]);
            if(key[Now]>1&&key[Now]<N+2) printf("%d ",key[Now]-1);
            if(ch[Now][1]) print(ch[Now][1]);
        }
    }S;
    int main()
    {
        int T,a,b;
        scanf("%d%d",&N,&T);
        S.build(1,N+2,0);
        while(T--){
            scanf("%d%d",&a,&b);
            S.revers(a,b+2);
        }
        S.print(S.rt);
        return 0;
    }



    N,M<=100000

  • 相关阅读:
    安卓开发遇到的报错信息
    工作记录
    答辩系统问题
    DWR
    前端vue 里的tab切换 减少dom操作
    前端拖动div 效果
    vue 点击按钮弹窗,点击关闭按钮关闭弹窗。
    前段开发 jq ajax数据处理详细讲解。
    vue计算属性computed和methods的区别
    前段开发 react native tab功能
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8643539.html
Copyright © 2011-2022 走看看