splay区间反转练手题
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=100005; int n,fa[N],ch[N][2],val[N],siz[N],tot,pos[N],rt; struct Node{ int id,v; }a[N]; bool cmp1(Node x,Node y) {return x.v==y.v?x.id<y.id:x.v<y.v;} bool cmp2(Node x,Node y) {return x.id<y.id;} bool rev[N]; inline void pushup(int x) {siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;} void pushdown(int x) { if(rev[x]) { swap(ch[x][0],ch[x][1]); rev[ch[x][0]]^=1,rev[ch[x][1]]^=1; rev[x]=0; } } int build(int f,int l,int r) { if(l>r) return 0; int now=++tot,mid=l+r>>1; val[now]=a[mid].v;fa[now]=f; pos[a[mid].v]=now; ch[now][0]=build(now,l,mid-1); ch[now][1]=build(now,mid+1,r); pushup(now); return now; } inline void rotate(int x) { int f=fa[x],ff=fa[f]; pushdown(f);pushdown(x); bool tag=ch[fa[x]][1]==x; ch[f][tag]=ch[x][tag^1]; fa[ch[f][tag]]=f; fa[f]=x; ch[x][tag^1]=f; fa[x]=ff; if(ff) ch[ff][f==ch[ff][1]]=x; pushup(f);pushup(x); } inline void splay(int x,int tar){ for(int f;(f=fa[x])!=tar;rotate(x)) if(fa[f]!=tar)rotate((x==ch[fa[x]][0])==(f==ch[fa[f]][0])?f:x); if(!tar) rt=x; } int nxt(){ pushdown(rt); int x=ch[rt][1]; while(pushdown(x),ch[x][0]) x=ch[x][0]; return x; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i+1].v),a[i+1].id=i+1; a[1].v=0;a[n+2].v=n+1;//a[1].id=1,a[n+2].id=n+2; sort(a+2,a+2+n,cmp1); for(int i=2;i<=n+1;i++) a[i].v=i-1; sort(a+2,a+2+n,cmp2); rt=build(0,1,n+2); for(int i=1;i<=n;i++) { int x=pos[i];splay(x,0); printf("%d ",siz[ch[x][0]]); x=nxt(); int y=pos[i-1]; splay(y,0); splay(x,y); rev[ch[x][0]]^=1; } }