思路:splay区间翻转的模板
代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int inf=0x3f3f3f3f;
int size[MAXN],key[MAXN],f[MAXN],ch[MAXN][2],lazy[MAXN];
int a[MAXN];
int sz,root;
int n,m;
bool get(int x)
{
return ch[f[x]][1]==x;
}
void update(int x)
{
size[x]=1;
if(ch[x][0])size[x]+=size[ch[x][0]];
if(ch[x][1])size[x]+=size[ch[x][1]];
}
void pushdown(int x)
{
if(lazy[x]&&x)
{
lazy[ch[x][0]]^=1;
lazy[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
lazy[x]=0;
}
}
void rotate(int x)
{
int old=f[x],oldf=f[old],whichx=get(x);
pushdown(old),pushdown(x);
ch[old][whichx]=ch[x][whichx^1];
f[ch[old][whichx]]=old;
ch[x][whichx^1]=old;
f[old]=x;
f[x]=oldf;
if(oldf)
ch[oldf][ch[oldf][1]==old]=x;
update(old);
update(x);
}
void splay(int x,int g)
{
for(int fa;(fa=f[x])!=g;rotate(x))
if(f[fa]!=g)
rotate((get(x)==get(f[fa]))?fa:x);
if(!g)root=x;
}
int find(int x)
{
int now=root;
while(1)
{
pushdown(now);
if(x<=size[ch[now][0]])now=ch[now][0];
else
{
x-=size[ch[now][0]]+1;
if(!x)return now;
now=ch[now][1];
}
}
}
int build(int l,int r,int x)
{
if(l>r)return 0;
int mid=(l+r)>>1;
int now=++sz;
key[now]=a[mid];
f[now]=x;
lazy[now]=0;
ch[now][0]=build(l,mid-1,now);
ch[now][1]=build(mid+1,r,now);
update(now);
return now;
}
void turn(int l,int r)
{
l=find(l);
r=find(r+2);
splay(l,0);
splay(r,l);
pushdown(root);
lazy[ch[ch[root][1]][0]]^=1;
}
void write(int now)
{
pushdown(now);
if(ch[now][0])write(ch[now][0]);
if(key[now]!=-inf&&key[now]!=inf)printf("%d ",key[now]);
if(key[ch[now][1]])write(ch[now][1]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=2;i<=n+1;i++)
a[i]=i-1;
a[1]=inf;
a[n+2]=-inf;
root=build(1,n+2,0);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
turn(x,y);
}
write(root);
return 0;
}