题目大意:给定一个$1\sim n$的序列,每次翻转一个区间,输出最后的序列。
解题思路:Splay的区间翻转操作。我借此打了个Splay的模板(运用内存池,但有些功能不确定正确,例如单点插入)。
大致思路就是,每次找到$l−1$和$r+1$两个节点,把$l−1$旋转到根,$r+1$旋转到根的右子树,则根的右子树的左子树就是$l,r$的区间。
对于翻转一个区间,直接打上标记,访问到这个节点时,下传标记并交换两个儿子节点。
注意访问$l−1$,$r+1$时可能访问到$0$和$n+1$,所以要多开两个节点。
最后输出即可。
C++ Code:
#include<bits/stdc++.h>
inline int readint(){char c=getchar();for(;!isdigit(c);c=getchar());int d=0;for(;isdigit(c);c=getchar())d=(d<<3)+(d<<1)+(c^'0');return d;
}
int n;
template<typename T>
class Splay{private:struct node{T value;int sz;bool rotag;node *fa,*ch[2];};public:node* rt;int n;private:node a[1000000],*stk[1000000];int top;inline void pushdown(node* t){if(t->rotag){node* x=t->ch[0];t->ch[0]=t->ch[1];t->ch[1]=x;if(t->ch[0]!=NULL)t->ch[0]->rotag^=1;if(t->ch[1]!=NULL)t->ch[1]->rotag^=1;t->rotag=0;}}inline node* newnode(T v,node* f){node* now=stk[--top];now->sz=1;now->value=v;now->fa=f;now->ch[0]=now->ch[1]=NULL;now->rotag=false;return now;}inline void dispose(node*&t){stk[top++]=t;t=NULL;}inline int findson(node* f,node* s){return(f->ch[1]==s)?1:0;}inline void update(node* t){t->sz=1;if(t->ch[0]!=NULL)t->sz+=t->ch[0]->sz;if(t->ch[1]!=NULL)t->sz+=t->ch[1]->sz;}inline void rotate(node* t){node* f=t->fa;node* g=f->fa;int a=findson(f,t),b=a^1;if(t->ch[b]!=NULL)t->ch[b]->fa=f;f->ch[a]=t->ch[b];t->ch[b]=f;f->fa=t;t->fa=g;if(g!=NULL)g->ch[findson(g,f)]=t;elsert=t;update(f);update(t);}public:Splay(){for(int i=0;i<1000000;++i)stk[i]=&a[i];top=1000000;}inline void splay(node* t,node* p){if(t==NULL)return;pushdown(t);while(t->fa!=p){node* f=t->fa;node* g=f->fa;if(g==p)rotate(t);elseif(findson(g,f)!=findson(f,t))rotate(t),rotate(t);elserotate(f),rotate(t);}}inline node* find(node* now,int y){while(now!=NULL){pushdown(now);int t;if(now->ch[0]==NULL)t=1;elset=now->ch[0]->sz+1;if(t==y)return now;if(t<y)y-=t,now=now->ch[1];elsenow=now->ch[0];}}inline void build(node*& p,int l,int r,node* f=NULL){if(l>r)return;int mid=l+r>>1;p=newnode(mid,f);build(p->ch[0],l,mid-1,p);build(p->ch[1],mid+1,r,p);update(p);}inline void insert(T val){if(rt==NULL)rt=newnode(val,NULL);int x;for(node* t=rt;t;t=t->son[x]){x=val>=t->value?1:0;if(t->ch[x]==NULL){t->son[x]=newnode(val,t);splay(t->son[x],rt);break;}}}inline void rev(node* p,int l,int r){node* pre=find(p,l),*suc=find(p,r);splay(pre,NULL);splay(suc,rt);if(rt->ch[1]->ch[0]!=NULL)rt->ch[1]->ch[0]->rotag^=1;}inline void print(node* p){if(p==NULL)return;pushdown(p);print(p->ch[0]);if(p->value>1&&p->value<n+2)printf("%d ",p->value-1);print(p->ch[1]);}inline void build(int nn){n=nn;build(rt,1,n+2);}
};
Splay<int>Tree;
int main(){n=readint();int m=readint();Tree.build(n);while(m--){int l=readint(),r=readint();Tree.rev(Tree.rt,l,r+2);}Tree.print(Tree.rt);return 0;
}