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上打标记,
然后翻转就好了。
  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 100000+5
 14 #define maxm 10000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define for0(i,n) for(int i=0;i<=(n);i++)
 18 #define for1(i,n) for(int i=1;i<=(n);i++)
 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 22 using namespace std;
 23 int read(){
 24     int x=0,f=1;char ch=getchar();
 25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 27     return x*f;
 28 }
 29 int n,m,sz,rt;
 30 int fa[maxn],c[maxn][2],id[maxn];
 31 int s[maxn];
 32 bool rev[maxn];
 33 void pushup(int x){
 34     int l=c[x][0],r=c[x][1];
 35     s[x]=s[l]+s[r]+1;
 36 }
 37 void pushdown(int x){
 38     int l=c[x][0],r=c[x][1];
 39     if(!rev[x])return;
 40     swap(c[x][1],c[x][0]);
 41     rev[l]^=1;rev[r]^=1;
 42     rev[x]=0;
 43 }
 44 void rotate(int x,int &k){
 45     int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
 46     if(y==k)k=x;
 47     else if(c[z][0]==y)c[z][0]=x;
 48     else c[z][1]=x;
 49     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
 50     c[y][l]=c[x][r];c[x][r]=y;
 51     pushup(y);pushup(x);
 52 }
 53 void splay(int x,int &k){
 54     while(x!=k){
 55         int y=fa[x],z=fa[y];
 56         if(y!=k){
 57             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
 58             else rotate(x,k);
 59         }
 60         else rotate(x,k);
 61     }
 62 }
 63 int find(int k,int rk){
 64     pushdown(k);
 65     int l=c[k][0],r=c[k][1];
 66     if(s[l]+1==rk)return k;
 67     else if(s[l]>=rk)return find(l,rk);
 68     else return find(r,rk-s[l]-1);
 69 }
 70 void rever(int l,int r){
 71     int x=find(rt,l),y=find(rt,r+2);
 72     splay(x,rt);splay(y,c[x][1]);
 73     int z=c[y][0];
 74     rev[z]^=1;
 75 }
 76 void build(int l,int r,int f){
 77     if(l>r)return ;
 78     int now=id[l],last=id[f];
 79     if(l==r){
 80         fa[now]=last;s[now]=1;
 81         if(l<f)c[last][0]=now;
 82         else c[last][1]=now;
 83         return ;
 84     }
 85     int mid=(l+r)>>1;now=id[mid];
 86     build(l,mid-1,mid);build(mid+1,r,mid);
 87     fa[now]=last;pushup(mid);
 88     if(mid<=f)c[last][0]=now;
 89     else c[last][1]=now;
 90 }
 91 int main(){
 92     //freopen("input.txt","r",stdin);
 93     //freopen("output.txt","w",stdout);
 94     n=read();m=read();
 95     for1(i,n+2)
 96         id[i]=++sz;
 97     build(1,n+2,0);rt=(n+3)>>1;
 98     for1(i,m){
 99         int l=read(),r=read();
100         rever(l,r);
101     }
102     for(int i=2;i<=n+1;i++)
103         printf("%d ",find(rt,i)-1);
104     return 0;
105 }
View Code

 

posted @ 2016-07-07 09:59  HTWX  阅读(93)  评论(0编辑  收藏  举报