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
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source
终于算是会写splay了吧。这次完完全全是重新写了一遍【果然写过一遍后总是回想把原来的复制过来】
这题就是个裸的splay,记得处理好标记下放。算是给自己留个splay模板吧
#include<cstdio>
#include<algorithm>
using namespace std;
struct tree
{
int l,r;
int ll,rr;
int fa;
int x;
int turn;
}tr[100003];
int root,tot;
/*
inline void up(int p)
{
}
*/
inline void down(int p)
{
int p1=tr[p].l,p2=tr[p].r;
if(tr[p].turn)
{
tr[p1].turn^=1;
tr[p2].turn^=1;
swap(tr[p1].l,tr[p1].r);
swap(tr[p2].l,tr[p2].r);
swap(tr[p1].ll,tr[p1].rr);
swap(tr[p2].ll,tr[p2].rr);
tr[p].turn=0;
}
}
inline void build(int &p,int l,int r)
{
int mid=(l+r)/2;
tot++;
p=tot;
tr[p].x=mid;
if(l==r)
return ;
if(mid-l>0)
{
tr[p].ll=mid-l;
build(tr[p].l,l,mid-1);
tr[tr[p].l].fa=p;
}
if(r-mid>0)
{
tr[p].rr=r-mid;
build(tr[p].r,mid+1,r);
tr[tr[p].r].fa=p;
}
//up(p)
}
inline void zig(int p)
{
int t=tr[p].l;
tr[p].l=tr[t].r;
tr[p].ll=tr[t].rr;
tr[t].r=p;
tr[t].rr+=tr[p].rr+1;
tr[t].fa=tr[p].fa;
tr[p].fa=t;
tr[tr[p].l].fa=p;
if(p==tr[tr[t].fa].l)
tr[tr[t].fa].l=t;
else
tr[tr[t].fa].r=t;
//up(p);
//up(t);
}
inline void zag(int p)
{
int t=tr[p].r;
tr[p].r=tr[t].l;
tr[p].rr=tr[t].ll;
tr[t].l=p;
tr[t].ll+=tr[p].ll+1;
tr[t].fa=tr[p].fa;
tr[p].fa=t;
tr[tr[p].r].fa=p;
if(p==tr[tr[t].fa].l)
tr[tr[t].fa].l=t;
else
tr[tr[t].fa].r=t;
//up(p);
//up(t);
}
int q[1000001];
inline void splay(int x,int &p)
{
int pt=0;
int i;
for(i=x;i!=0;i=tr[i].fa)
{
pt++;
q[pt]=i;
}
while(pt>0)
{
down(q[pt]);
pt--;
}
int fa=tr[p].fa;
while(tr[x].fa!=fa)
{
int y=tr[x].fa,z=tr[y].fa;
if(z==fa)
{
if(x==tr[y].l)
zig(y);
else
zag(y);
}
else if(y==tr[z].l)
{
if(x==tr[y].l){zig(z);zig(y);}
else{zag(y);zig(z);}
}
else if(y==tr[z].r)
{
if(x==tr[y].r){zag(z);zag(y);}
else{zig(y);zag(z);}
}
}
p=x;
}
inline int find(int p,int rank)
{
down(p);
if(tr[p].ll+1==rank)
return p;
if(tr[p].ll+1<rank)
return find(tr[p].r,rank-tr[p].ll-1);
else
return find(tr[p].l,rank);
}
inline void turn(int s,int t)
{
int u=find(root,s),v=find(root,t+2);
splay(u,root);
splay(v,tr[root].r);
int p=tr[tr[root].r].l;
tr[p].turn^=1;
swap(tr[p].l,tr[p].r);
swap(tr[p].ll,tr[p].rr);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i;
build(root,0,n+1);
int s,t;
for(i=1;i<=m;i++)
{
scanf("%d%d",&s,&t);
turn(s,t);
}
for(i=1;i<=n-1;i++)
{
int p=find(root,i+1);
printf("%d ",tr[p].x);
}
int p=find(root,n+1);
printf("%d ",tr[p].x);
return 0;
}