题意:就是splay的区间翻转 然后直接加到序列的末尾
解法:大概是很轻松的
#include<cstdio>
#include<string.h>
#include<iostream>
using namespace std;
#define maxn 222222
#define ls ch[rt][0]
#define rs ch[rt][1]
#define rrs ch[root][1]
#define rls ch[root][0]
int val[maxn],num[maxn],ch[maxn][2],fa[maxn],root,cnt,rev[maxn];
inline void up(int rt){num[rt]=num[ls]+num[rs]+1;}
inline void down(int rt){
if(rev[rt]){
rev[ls]^=1;rev[rs]^=1;swap(ls,rs);rev[rt]=0;
}
}
inline void node(int rt){fa[rt]=val[rt]=ls=rs=0;num[rt]=1;rev[rt]=0;}
inline void rot(int rt){
int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side];
fa[ll]=f,ch[f][side]=ll;
fa[rt]=fa[f],ch[fa[f]][ch[fa[f]][1]==f]=rt;
fa[f]=rt,ch[rt][!side]=f;
up(f),up(rt);
}
inline void splay(int rt,int aim){
while(fa[rt]!=aim){
down(rt);
int f=fa[rt],ff=fa[f];
if(ff==aim)rot(rt);
else if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt);
else rot(rt),rot(rt);
}if(!aim)root=rt;
}
inline void find(int tot,int sub){
int rt=sub;
while(1){
down(rt);
if(num[ls]+1==tot)break;
if(num[ls]>=tot)rt=ls;
else tot-=num[ls]+1,rt=rs;
}splay(rt,fa[sub]);
}
inline void build(int n){
cnt=0;node(0);num[0]=0;
node(++cnt);
for(int i=2;i<=n+1;++i){
node(++cnt);fa[i-1]=i;ch[i][0]=i-1;val[i]=i-1;up(i);
}
node(++cnt);fa[cnt]=cnt-1;ch[cnt-1][1]=cnt;
root=cnt-1;up(root);
}
int ans[maxn],sz;
void answer(int rt){
down(rt);
if(ls)answer(ls);
ans[sz++]=val[rt];
if(rs)answer(rs);
}
int main(){
int n,m,l,r;
while(~scanf("%d%d",&n,&m)){
build(n);
while(m--){
scanf("%d%d",&l,&r);
find(l,root);find(r-l+2,rrs);
int rt=ch[rrs][0];
// printf("%d %d\n",val[root],val[rrs]);
ch[rrs][0]=0;
rev[rt]^=1;up(rrs);up(root);n-=num[rt];
find(n+1,root);find(1,rrs);
fa[rt]=rrs,ch[rrs][0]=rt;
up(rrs),up(root),n+=num[rt];
}
sz=0;
answer(root);
for(int i=1;i<=n;++i)printf("%d\n",ans[i]);
}
return 0;
}