zoukankan      html  css  js  c++  java
  • 【BZOJ3223】 Tyvj 1729 文艺平衡树 Splay

    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

    区间翻转,注意kth时和标记时下方标记,没了。
      1 #include <cstdio>
      2 #include <iostream>
      3 #define N 100100
      4 using namespace std;
      5 struct SplayNode
      6 {
      7     SplayNode *fa,*ch[2];
      8     SplayNode();
      9     int data,num,size;
     10     bool rev;
     11     int chr() {return this==fa->ch[1];}
     12     void updata() {size=ch[0]->size+ch[1]->size+1;}
     13     void mark() {rev=rev^1;}
     14     void push()
     15     {
     16         if (rev)
     17         {
     18             rev=rev^1;;
     19             ch[0]->mark();
     20             ch[1]->mark();
     21             swap(ch[0],ch[1]);
     22         }
     23     }
     24 }*null;
     25 SplayNode::SplayNode() {fa=ch[0]=ch[1]=null; rev=0; size=0;} 
     26 int n,m;
     27 int a[N];
     28 namespace Splay
     29 {
     30     SplayNode *Root;
     31     SplayNode *Build(int l,int r)
     32     {
     33         if (l>r) return null;
     34         int mid=(l+r)>>1;
     35         SplayNode *R=new SplayNode;
     36         R->data=a[mid];
     37         R->ch[0]=Build(l,mid-1);
     38         R->ch[1]=Build(mid+1,r);
     39         R->ch[0]->fa=R;
     40         R->ch[1]->fa=R;
     41         R->updata();
     42         return R;
     43     }
     44     void MakeTree()
     45     {
     46         null=new SplayNode;
     47         *null=SplayNode();
     48         Root=Build(1,n);
     49     }
     50     void rotate(SplayNode *x)
     51     {
     52         SplayNode *r=x->fa;
     53         if (r==null || x==null) return;
     54         int t=x->chr();
     55         r->ch[t]=x->ch[t^1];
     56         r->ch[t]->fa=r;
     57         if (r->fa==null) Root=x;
     58         else r->fa->ch[r->chr()]=x;
     59         x->fa=r->fa;
     60         x->ch[t^1]=r;
     61         r->fa=x;
     62         x->updata();
     63         r->updata();
     64     }
     65     void splay(SplayNode *x,SplayNode *y)
     66     {
     67         for (;x->fa!=y;rotate(x))
     68             if (x->fa->fa!=y)
     69                 if (x->fa->chr()==x->chr()) rotate(x->fa);
     70                 else rotate(x);
     71     }
     72     SplayNode *Kth(int k)
     73     {
     74         SplayNode *r=Root;
     75         if (k<1 || k>n) return null;
     76         while (r!=null)
     77         {
     78             r->push();
     79             if (k<=r->ch[0]->size) r=r->ch[0];
     80             else if (k==r->ch[0]->size+1) return r;
     81             else 
     82             {
     83                 k-=r->ch[0]->size+1;
     84                 r=r->ch[1];
     85             }
     86         }
     87         return null;
     88     }
     89     void reverse(int l,int r)
     90     {
     91         SplayNode *q=Kth(l-1);
     92         SplayNode *p=Kth(r+1);
     93         if (q==null && p==null) 
     94         {
     95             Root->mark();
     96             return;
     97         }
     98         if (q==null)
     99         {
    100             splay(p,null);
    101             p->ch[0]->mark();
    102             return;
    103         }
    104         if (p==null)
    105         {
    106             splay(q,null);
    107             q->ch[1]->mark();
    108             return;
    109         }
    110         q->push();
    111         splay(q,null);
    112         p->push();
    113         splay(p,q);
    114         p->ch[0]->mark();        
    115     }
    116     void dfs(SplayNode *x)
    117     {
    118         if (x==null) return;
    119         x->push();
    120         dfs(x->ch[0]);
    121         printf("%d ",x->data);
    122         dfs(x->ch[1]);
    123     }
    124     
    125 }
    126 int main()
    127 {
    128     scanf("%d%d",&n,&m);
    129     for (int i=1;i<=n;i++) a[i]=i;
    130     Splay::MakeTree();
    131     //Splay::dfs(Splay::Root);
    132 //    cout<<endl;
    133     for (int i=1;i<=m;i++)
    134     {
    135         int x,y;
    136         scanf("%d%d",&x,&y);
    137         Splay::reverse(x,y);
    138     //    Splay::dfs(Splay::Root);
    139     //    cout<<endl;
    140     }
    141     Splay::dfs(Splay::Root);
    142     return 0;
    143 }
    View Code
    —Anime Otaku Save The World.
  • 相关阅读:
    Java入门:基础算法之求数组元素的和
    Java入门:基础算法之计算三角形面积
    Java入门:基础算法之计算园的面积
    Java入门:创建多个对象
    编程语言教程书该怎么写: 向K&R学习!
    Java入门:一些初学者需要掌握的基础算法程序——二分查找
    Java入门:一些初学者需要掌握的基础算法程序——逆序输出
    Java入门:Java中获取键盘输入值的三种方法
    Java注释规范整理
    8大排序算法图文讲解
  • 原文地址:https://www.cnblogs.com/DMoon/p/5284799.html
Copyright © 2011-2022 走看看