题意
- m个操作,每次将一个区间翻转然后剪切这个区间并粘贴到尾部,求最后的数列
题解
代码
#include<cstdio>
#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=2e5+10;
int n,m,l,r;
struct splay_tree{
int tot,root,ch[maxn][2],fa[maxn],siz[maxn];
int minn[maxn],val[maxn],mark[maxn][3];
splay_tree(){
tot=2;root=1;
ch[1][1]=2;fa[2]=1;fa[1]=0;siz[1]=2;siz[2]=1;val[2]=minn[2]=inf;val[1]=minn[1]=-inf;
}
int dir(int x){
return ch[fa[x]][1]==x;
}
void pushup(int x){
siz[x]=1;
if(ch[x][0]) siz[x]+=siz[ch[x][0]];
if(ch[x][1]) siz[x]+=siz[ch[x][1]];
}
void down(int x){
if(mark[x][0]){
swap(ch[x][0],ch[x][1]);
mark[ch[x][0]][0]^=1;
mark[ch[x][1]][0]^=1;
mark[x][0]=0;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],k=dir(x);
down(y);down(x);
ch[y][k]=ch[x][k^1];fa[ch[x][k^1]]=y;
ch[z][dir(y)]=x;fa[x]=z;
ch[x][k^1]=y;fa[y]=x;
pushup(y);pushup(x);
}
void splay(int x,int goal=0){
while(fa[x]!=goal){
int y=fa[x],z=fa[y];
if(z!=goal) {
if(dir(x)==dir(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
if(!goal) root=x;
}
int kth(int x){
int cur=root;
while(true){
down(cur);
if(ch[cur][0]&&x<=siz[ch[cur][0]]){
cur=ch[cur][0];
}else if(x>siz[ch[cur][0]]+1){
x-=(siz[ch[cur][0]]+1);
cur=ch[cur][1];
}else return cur;
}
}
void insert(int pos,int value){
int cur=kth(pos),rson=kth(pos+1);
splay(cur),splay(rson,root);
ch[rson][0]=++tot;fa[tot]=rson;
ch[tot][0]=ch[tot][1]=0;siz[tot]=1;
val[tot]=minn[tot]=value;
pushup(rson);pushup(root);
splay(cur);
}
void reverse(int l,int r){
int cur=kth(l),rson=kth(r+2);
splay(cur);splay(rson,root);
mark[ch[rson][0]][0]^=1;int tmp=ch[rson][0];
ch[rson][0]=0;
pushup(rson);pushup(root);
cur=kth(n+1-(r-l+1)),rson=kth(n+2-(r-l+1));
splay(cur);splay(rson,root);
ch[rson][0]=tmp;fa[tmp]=rson;
pushup(rson);pushup(root);
}
void mid_visit(int cur){
down(cur);
if(ch[cur][0]) mid_visit(ch[cur][0]);
if(val[cur]!=inf&&val[cur]!=-inf)printf("%d\n",val[cur]);
if(ch[cur][1]) mid_visit(ch[cur][1]);
}
}tree;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) tree.insert(i,i);
for(int i=1;i<=m;i++){
scanf("%d %d",&l,&r);
tree.reverse(l,r);
}
tree.mid_visit(tree.root);
}