bzoj 3223 文艺平衡树 splay 区间翻转

Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 17715  Solved: 7769
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

 

1.n的数据范围:n<=100000

2.每个数的数据范围:[-2e9,2e9]

 

Source

 
题解:
  区间翻转就没了。
  1 #include<cstring>
  2 #include<cmath>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstdio>
  6 
  7 #define inf 1000000007
  8 #define N 100007
  9 #define ls c[p][0]
 10 #define rs c[p][1]
 11 using namespace std;
 12 inline int read()
 13 {
 14     int x=0,f=1;char ch=getchar();
 15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
 16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
 17     return x*f;
 18 }
 19 
 20 int n,m,rt;
 21 int fa[N],val[N],rev[N],mx[N],sz[N],flag[N],c[N][2];
 22 
 23 inline void update(int p)
 24 {
 25     sz[p]=sz[ls]+sz[rs]+1;
 26 }
 27 inline void pushdown(int p)
 28 {
 29     if (rev[p])
 30     {
 31         rev[p]^=1;
 32         rev[ls]^=1,rev[rs]^=1;
 33         swap(c[p][1],c[p][0]);
 34     }
 35 }
 36 void rotate(int x,int &k)
 37 {
 38     int y=fa[x],z=fa[y],l,r;
 39     if (c[y][0]==x) l=0;else l=1;r=l^1;
 40     if (y==k) k=x;//交换后x就等于y 
 41     else if (c[z][0]==y) c[z][0]=x;
 42     else c[z][1]=x;
 43     fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
 44     c[y][l]=c[x][r],c[x][r]=y;
 45     update(y),update(x);
 46 }
 47 void splay(int x,int &k)
 48 {
 49     while(x!=k)
 50     {
 51         int y=fa[x],z=fa[y];
 52         if (y!=k)
 53         {
 54             if (c[y][0]==x^c[z][0]==y) rotate(x,k);
 55             else rotate(y,k);
 56         }
 57         rotate(x,k);
 58     }
 59 }
 60 int find(int p,int num)
 61 {
 62     pushdown(p);
 63     if (sz[ls]>=num) return find(ls,num);
 64     else if (sz[ls]+1==num) return p;
 65     else return find(rs,num-sz[ls]-1); 
 66 }
 67 void spin(int l,int r)
 68 {
 69     int x=find(rt,l),y=find(rt,r+2);
 70     splay(x,rt),splay(y,c[x][1]);
 71     int now=c[c[x][1]][0];
 72     rev[now]^=1;
 73 }
 74 void build(int l,int r,int p)
 75 {
 76     if (l>r) return;
 77     if (l==r)
 78     {
 79         fa[l]=p,sz[l]=1,val[l]=l;
 80         if (l<p) c[p][0]=l;
 81         else c[p][1]=l;
 82         return;
 83     }
 84     int mid=(l+r)>>1;
 85     build(l,mid-1,mid),build(mid+1,r,mid);
 86     fa[mid]=p,val[mid]=mid;
 87     if (mid<p) c[p][0]=mid;
 88     else c[p][1]=mid;
 89     update(mid);
 90 }
 91 int main()
 92 {    
 93     n=read(),m=read();
 94     build(1,n+2,0),rt=(n+3)>>1;
 95     while(m--)
 96     {
 97         int x=read(),y=read();
 98         spin(x,y);
 99     }
100     for (int i=1;i<=n;i++)
101     {
102         int x=find(rt,i+1);
103         if (i==1) cout<<val[x]-1;
104         else cout<<" "<<val[x]-1;
105     }
106 }

 

posted @ 2017-12-24 14:15  Kaiser-  阅读(219)  评论(0编辑  收藏  举报