[Tyvj 1729]文艺平衡树

来源:互联网 发布:php网页聊天室原理 编辑:程序博客网 时间:2024/05/16 15:07
P1729 文艺平衡树
时间: 1000ms / 空间: 131072KiB / Java类名: Main

背景

此为平衡树系列第二道:文艺平衡树

描述

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

输入格式

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n

输出格式

输出一行n个数字,表示原始序列经过m次变换后的结果

测试样例1

输入

5 3 
1 3 
1 3 
1 4

输出

4 3 2 1 5

备注

n,m<=100000 


Splay的特殊应用,当前点的size域代表的是它在数列中的位置,当前点的下标即为此数(可以再维护一个域,只不过这个域和下标是相等的)。所以我们需要写一个查询第k大来旋转更改区间,每次查询的时候要把标记向下传递。此时再进行Splay只需要pushdown一下当前点就可以了,因为上面都木有标记了!

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define maxn 100010using namespace std;struct Tree{int ch[2],rev,fa,siz;#define c(x,y) tree[x].ch[y]#define rev(x) tree[x].rev#define fa(x) tree[x].fa#define siz(x) tree[x].siz}tree[maxn];int n,root,m;void Pushup(int x){if(x)siz(x)=siz(c(x,0))+siz(c(x,1))+1;}void Pushdown(int x){if(rev(x)){swap(c(x,0),c(x,1));rev(c(x,0))^=1;rev(c(x,1))^=1;rev(x)=0;}}void Rotate(int p,int x){int mark=p==c(x,1),y=c(p,mark^1),z=fa(x);if(x==c(z,0))c(z,0)=p;if(x==c(z,1))c(z,1)=p;if(y)fa(y)=x;fa(p)=z;fa(x)=p;c(p,mark^1)=x;c(x,mark)=y;Pushup(x);}void Splay(int p,int k){Pushdown(p);while(fa(p)!=k){int x=fa(p),y=fa(x);if(y==k)Rotate(p,x);else if(x==c(y,0)^p==c(x,0))Rotate(p,x),Rotate(p,y);else Rotate(x,y),Rotate(p,x);}if(!k)root=p;Pushup(p);}int Kth(int k){int now=root;while(now){Pushdown(now);if(k>siz(c(now,0))){k-=siz(c(now,0))+1;if(!k)return now;now=c(now,1);}else now=c(now,0);}return 0;}void Rever(int l,int r){l=Kth(l),r=Kth(r+2);Splay(l,0);Splay(r,l);rev(c(r,0))^=1;}void Build(int l,int r,int f){if(l>r)return;if(l==r){if(f)c(f,l>f)=l;fa(l)=f;siz(l)=1;return;}int mid=(l+r)>>1;Build(l,mid-1,mid);Build(mid+1,r,mid);if(f)c(f,mid>f)=mid;fa(mid)=f;Pushup(mid);}void Print(int x){if(!x)return;Pushdown(x);Print(c(x,0));if(x!=1&&x!=n+2)printf("%d ",x-1);Print(c(x,1));}int main(){scanf("%d%d",&n,&m);int l,r;Build(1,n+2,0);root=(n+3)>>1;for(int i=1;i<=m;i++){scanf("%d%d",&l,&r);Rever(l,r);}Print(root);return 0;}



0 0