题解:
splay翻转(只有翻转
sgu ac,spoj tle
代码:
#pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int n,m,sz,rt,pre[N],cas,l,r,c[N][],alen,data[N],size[N],rev[N];
void pushup(int k)
{
size[k]=size[c[k][]]+size[c[k][]]+;
}
void pushdown(int k)
{
int l=c[k][],r=c[k][];
if(rev[k])
{
swap(c[k][],c[k][]);
rev[l]^=;rev[r]^=;
rev[k]=;
}
}
void rotate(int x,int &k)
{
int y=pre[x],z=pre[y],l,r;
if(c[y][]==x)l=;
else l=;
r=l^;
if(y==k)k=x;
else {if(c[z][]==y)c[z][]=x;else c[z][]=x;}
pre[x]=z;pre[y]=x;pre[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=pre[x],z=pre[y];
if(y!=k)
{
if(c[y][]==x^c[z][]==y)rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
int find(int k,int rank)
{
pushdown(k);
int l=c[k][],r=c[k][];
if (size[l]+==rank)return k;
else if (size[l]>=rank)return find(l,rank);
else return find(r,rank-size[l]-);
}
void change(int l,int r)
{
int x=find(rt,l),y=find(rt,r+);
splay(x,rt);splay(y,c[x][]);
int z=c[y][];
rev[z]^=;
}
void build(int l,int r,int f)
{
if(l>r)return;
int now=data[l],last=data[f];
if(l==r)
{
pre[now]=last;size[now]=;
if(l<f)c[last][]=now;
else c[last][]=now;
return;
}
int mid=(l+r)>>;now=data[mid];
build(l,mid-,mid);
build(mid+,r,mid);
pre[now]=last;pushup(mid);
if(mid<f)c[last][]=now;
else c[last][]=now;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n+;i++)data[i]=++sz;
build(,n+,);rt=(n+)>>;
while (m--)
{
scanf("%d%d",&l,&r);
if (l!=r)change(l,r);
}
for(int i=;i<=n+;i++)printf("%d\n",find(rt,i)-);
}