BZOJ 3223: Tyvj 1729 文艺平衡树

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3629  Solved: 2053
[Submit][Status][Discuss]

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

平衡树

分析:

第一次写Splay维护区间翻转操作...

我们可以用线段树的lazy标记的思想,如果要翻转某个区间,就在子节点打上标记,然后每次访问到带标记的节点的时候就下放标记...

对于每一个节点,它的权值就是初始序列的序号,每一次翻转区间[l,r]的时候,我们先把排名为l-1的节点转到根节点,这样就保证了[l,+∞)都在根节点的右子树中,然后我们再找到排名为r-1节点,把它转到根节点的右儿子的位置,这样就保证了[l,r]都在r-1节点的左儿子,这样我们直接打标记就好...

代码:

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 //by NeighThorn
  6 using namespace std;
  7 
  8 const int maxn=100000+5;
  9 
 10 int n,m;
 11 int tot,root,w[maxn],ls[maxn],rs[maxn],fa[maxn],siz[maxn],lazy[maxn];
 12 
 13 inline void zig(int x){
 14     int y=fa[x],tmp=siz[y];
 15     if(rs[x])
 16         ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
 17     else
 18         ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
 19     fa[x]=fa[y];
 20     if(fa[x]){
 21         if(ls[fa[x]]==y)
 22             ls[fa[x]]=x;
 23         else
 24             rs[fa[x]]=x;
 25     }
 26     fa[y]=x,rs[x]=y;
 27 }
 28 
 29 inline void zag(int x){
 30     int y=fa[x],tmp=siz[y];
 31     if(ls[x])
 32         rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
 33     else
 34         rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
 35     fa[x]=fa[y];
 36     if(fa[x]){
 37         if(ls[fa[x]]==y)
 38             ls[fa[x]]=x;
 39         else
 40             rs[fa[x]]=x;
 41     }
 42     fa[y]=x,ls[x]=y;
 43 }
 44 
 45 inline void splay(int x,int z){
 46     while(fa[x]!=z){
 47         int y=fa[x];
 48         if(fa[y]==z){
 49             if(ls[y]==x)
 50                 zig(x);
 51             else
 52                 zag(x);
 53         }
 54         else{
 55             if(ls[fa[y]]==y){
 56                 if(ls[y]==x)
 57                     zig(y),zig(x);
 58                 else
 59                     zag(x),zig(x);
 60             }
 61             else{
 62                 if(rs[y]==x)
 63                     zag(y),zag(x);
 64                 else
 65                     zig(x),zag(x);
 66             }
 67         }
 68     }
 69     if(!z)
 70         root=x;
 71 }
 72 
 73 inline void ins(int rt,int x){
 74     if(rt==0)
 75         w[++tot]=x,siz[tot]=1,root=tot;
 76     else if(x<w[rt]){
 77         if(ls[rt]==0)
 78             w[++tot]=x,siz[tot]=1,fa[tot]=rt,siz[rt]++,ls[rt]=tot,splay(tot,0);
 79         else
 80             siz[rt]++,ins(ls[rt],x);
 81     }
 82     else{
 83         if(rs[rt]==0)
 84             w[++tot]=x,siz[tot]=1,siz[rt]++,fa[tot]=rt,rs[rt]=tot,splay(tot,0);
 85         else
 86             siz[rt]++,ins(rs[rt],x);
 87     }
 88 }
 89 
 90 inline void push_down(int x){
 91     lazy[x]=0;lazy[ls[x]]^=1,lazy[rs[x]]^=1;
 92     swap(ls[x],rs[x]);
 93 }
 94 
 95 inline int find(int rt,int x){
 96     if(lazy[rt])
 97         push_down(rt);
 98     if(siz[ls[rt]]+1==x){
 99         splay(rt,0);return rt;
100     }
101     else if(siz[ls[rt]]>=x)
102         return find(ls[rt],x);
103     else
104         return find(rs[rt],x-siz[ls[rt]]-1);
105 }
106 
107 inline void dfs(int rt){
108     if(lazy[rt])
109         push_down(rt);
110     if(!rt)
111         return;
112     if(!ls[rt])
113         printf("%d ",w[rt]),dfs(rs[rt]);
114     else
115         dfs(ls[rt]),printf("%d ",w[rt]),dfs(rs[rt]);
116 }
117 
118 signed main(void){
119     memset(ls,0,sizeof(ls));
120     memset(rs,0,sizeof(rs));
121     memset(fa,0,sizeof(fa));
122     memset(siz,0,sizeof(siz));
123     memset(lazy,0,sizeof(lazy));
124     scanf("%d%d",&n,&m);root=tot=0;
125     for(int i=1;i<=n;i++)
126         ins(root,i);
127     for(int i=1,l,r;i<=m;i++){
128         scanf("%d%d",&l,&r);
129         if(l==1&&r==tot)
130             lazy[root]^=1;
131         else if(l==1)
132             r=find(root,r+1),splay(r,0),lazy[ls[r]]^=1;
133         else if(r==tot)
134             l=find(root,l-1),splay(l,0),lazy[rs[l]]^=1;
135         else
136             l=find(root,l-1),r=find(root,r+1),splay(l,0),splay(r,l),lazy[ls[r]]^=1;
137     }
138     dfs(root);puts("");
139     return 0;
140 }
View Code

by NeighThorn

 

posted @ 2016-12-09 23:20  NeighThorn  阅读(224)  评论(0编辑  收藏  举报