题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3223
带翻转的splay 只需要把l-1提到根位置,r+1提到根的右子树,那么r+1的左子树就是[l,r]
对反转次数打标记
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #define lson i<<1 #define rson i<<1|1 using namespace std; const int N=1e5+5; const int inf=0x3f3f3f3f; int n,m; int f[N],ch[N][2],mark[N],sz[N],key[N]; int root,tot; int a[N]; inline int get(int x) { return ch[f[x]][1]==x; } inline void pushup(int x) { sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; } void pushdown(int x) { if (x&&mark[x]) { mark[ch[x][0]]^=1; mark[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); mark[x]=0; } } int build(int l,int r,int fa) { if (l>r) return 0; int mid=(l+r)>>1; int now=++tot; f[now]=fa;key[now]=a[mid];mark[now]=0; ch[now][0]=build(l,mid-1,now); ch[now][1]=build(mid+1,r,now); pushup(now); return now; } int Find(int x) { int now=root; while(1) { pushdown(now); if (x<=sz[ch[now][0]]) now=ch[now][0]; else { x=x-sz[ch[now][0]]-1; if (!x) return now; now=ch[now][1]; } } } void Rotate(int x) { pushdown(f[x]); pushdown(x); int fa=f[x],ff=f[fa],kind=get(x); ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa; ch[x][kind^1]=fa;f[fa]=x; f[x]=ff; if (ff) ch[ff][ch[ff][1]==fa]=x; pushup(fa); pushup(x); } void splay(int x,int y) { for(int fa;(fa=f[x])!=y;Rotate(x)) if (f[fa]!=y) Rotate((get(x)==get(fa))?fa:x); if (y==0) root=x; } void out(int now) { pushdown(now); if (ch[now][0]) out(ch[now][0]); if (key[now]!=inf&&key[now]!=-inf) printf("%d ",key[now]); if (ch[now][1]) out(ch[now][1]); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(sz,0,sizeof(sz)); tot=0; a[1]=-inf;a[n+2]=inf; for(int i=1;i<=n;i++) a[i+1]=i; root=build(1,n+2,0); int x,y; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); // x-1 y+1 还有-inf 所以就是x-1+1 y+1+1 int xx=Find(x); int yy=Find(y+2); splay(xx,0); splay(yy,xx); mark[ch[ch[root][1]][0]]^=1; } out(root); printf(" "); } return 0; }