3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBDescription
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source
Splay区间旋转操作的练手题。
见代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define MAXN 200008 6 using namespace std; 7 8 int n,m,fa[MAXN],tr[MAXN][2],rt,size[MAXN],sz,flag[MAXN]; 9 10 inline int read(){ 11 char ch=getchar(); 12 int x=0,f=1; 13 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) f=-1; ch=getchar();} 14 while(ch>=‘0‘&&ch<=‘9‘) x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar(); 15 return x*f; 16 } 17 18 void pushup(int k){ 19 int l=tr[k][0],r=tr[k][1]; 20 size[k]=size[l]+size[r]+1; 21 } 22 23 void pushdown(int k){ 24 int l=tr[k][0],r=tr[k][1]; 25 if(flag[k]){ 26 swap(tr[k][0],tr[k][1]); 27 flag[l]^=1; flag[r]^=1; 28 flag[k]=0; 29 } 30 } 31 32 void rotate(int x,int &k){ 33 int l,r,y=fa[x],z=fa[y]; 34 if(y==k) k=x; 35 else{ 36 if(tr[z][0]==y) tr[z][0]=x; else tr[z][1]=x; 37 } 38 if(tr[y][0]==x) l=0; else l=1; 39 r=l^1; 40 fa[x]=z; fa[y]=x; fa[tr[x][r]]=y; 41 tr[y][l]=tr[x][r]; tr[x][r]=y; 42 pushup(y); pushup(x); 43 } 44 45 void splay(int x,int &k){ 46 int y,z; 47 while(x!=k){ 48 y=fa[x]; z=fa[y]; 49 if(y!=k){ 50 if(tr[y][0]==x^tr[z][0]==y) rotate(x,k); 51 else rotate(y,k); 52 } 53 rotate(x,k); 54 } 55 } 56 57 void build(int l,int r,int f){ 58 if(l>r) return; 59 int now=l,last=f; 60 if(l==r){ 61 fa[now]=last; size[now]=1; 62 if(l<f) tr[last][0]=l; 63 else tr[last][1]=l; 64 return; 65 } 66 int mid=(l+r)>>1; now=mid; 67 build(l,mid-1,mid); build(mid+1,r,mid); 68 fa[now]=last; pushup(mid); 69 if(mid<f) tr[last][0]=now; 70 else tr[last][1]=now; 71 } 72 73 int find(int k,int x){ 74 pushdown(k); 75 int t1=tr[k][0],t2=tr[k][1]; 76 if(size[t1]+1==x) return k; 77 if(size[t1]>=x) return find(t1,x); 78 return find(t2,x-size[t1]-1); 79 } 80 81 void rever(int l,int r){ 82 int t1=find(rt,l),t2=find(rt,r+2); 83 splay(t1,rt); splay(t2,tr[t1][1]); 84 int k=tr[t2][0]; 85 flag[k]^=1; 86 } 87 88 int main(){ 89 n=read(); m=read(); 90 build(1,n+2,0); rt=(n+3)>>1; 91 for(int i=1;i<=m;i++){ 92 int x,y; 93 x=read(); y=read(); 94 rever(x,y); 95 } 96 for(int i=1;i<=n;i++){ 97 printf("%d ",find(rt,i+1)-1); 98 } 99 } 100