题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=3223
思路
非常基础的数据结构题。。。
要求支持对一个序列进行翻转操作。。。。
很显然就只能用splay了对吧。。。
比较简单,没有用到什么很难的lazy tag,就是只需要维护一个翻转标记的lazy tag就ok了。
其他比较难一点的splay题我再找找复习。。。
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 110000
using namespace std;
int a[MAXN];
int nCount=0;
int ch[MAXN][2],fa[MAXN],size[MAXN],val[MAXN],root;
bool rev[MAXN];
inline void pushup(int o)
{
size[o]=size[ch[o][0]]+size[ch[o][1]]+1;
}
inline void build(int L,int R,int &o,int father)
{
if(L>R) return;
int M=(L+R)>>1;
o=++nCount;
val[o]=a[M];
size[o]=1;
fa[o]=father;
if(L==R) return;
build(L,M-1,ch[o][0],o);
build(M+1,R,ch[o][1],o);
pushup(o);
}
inline void pushdown(int o)
{
if(rev[o])
{
swap(ch[o][0],ch[o][1]);
rev[ch[o][0]]^=1; //!!!!!
rev[ch[o][1]]^=1;
rev[o]=false;
}
}
inline void rot(int x,int &k)
{
int y=fa[x],z=fa[y];
int p,q;
if(ch[y][0]==x) p=0;
else p=1;
q=p^1;
if(y!=k)
{
if(ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
}
else k=x;
fa[x]=z;
fa[y]=x;
ch[y][p]=ch[x][q];
fa[ch[x][q]]=y;
ch[x][q]=y;
pushup(y); //!!!!
pushup(x);
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if(y!=k) //!!!!!!!
{
if((ch[y][0]==x)==(ch[z][0]==y)) rot(y,k);
else rot(x,k);
}
rot(x,k);
}
}
int getKth(int o,int k)
{
pushdown(o); //!!!!!!
if(size[ch[o][0]]==k-1) return o;
if(size[ch[o][0]]>=k) return getKth(ch[o][0],k);
return getKth(ch[o][1],k-size[ch[o][0]]-1);
}
void reverse(int L,int R) //翻转[L,R]
{
int x=getKth(root,L-1),y=getKth(root,R+1);
splay(x,root);
splay(y,ch[x][1]);
int z=ch[y][0];
rev[z]^=1;
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=2;i<=n+1;i++)
a[i]=i-1;
build(1,n+2,root,0);
while(q--)
{
int L,R;
scanf("%d%d",&L,&R);
reverse(L+1,R+1);
}
for(int i=2;i<=n+1;i++)
printf("%d ",val[getKth(root,i)]);
printf("\n");
return 0;
}