1552: [Cerc2007]robotic sort
这道题用splay写 先离散化数据保证按题目所述顺序来写 按原序作为键值建树 维护区间最小值去跑 每次将i的位置 和 n的位置x和y找出来后 将x旋转到root y旋转到x的有儿子 这时y的左子树就是所求区间 找出区间最小值和他的位置之后 旋转最小值到root 这时他左子树的大小+1就是他现处位置 然后将i到最小值位置中间的区间打上标记等待旋转 这样全部处理完就okay了
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } const int M=100505,inf=1000000000; int n,root,c[M][2],mn[M],pos[M],ans[M],rev[M],fa[M],size[M],v[M],top,s[M]; struct node{int v,pos;}tr[M]; bool cmp(node a,node b){return ((a.v<b.v)||(a.v==b.v&&a.pos<b.pos));} bool operator<(node a,node b){return a.pos<b.pos;} void push_up(int k){ int l=c[k][0],r=c[k][1]; size[k]=size[l]+size[r]+1; pos[k]=k; mn[k]=v[k]; if(mn[l]<mn[k]){ mn[k]=mn[l]; pos[k]=pos[l];} if(mn[r]<mn[k]){ mn[k]=mn[r]; pos[k]=pos[r];} } void push_down(int k){ int l=c[k][0],r=c[k][1]; rev[k]=0; rev[l]^=1; rev[r]^=1; swap(c[k][0],c[k][1]); } int build(int l,int r){ if(l>r) return 0; int m=(l+r)>>1; size[m]=1; pos[m]=m; c[m][0]=build(l,m-1); c[m][1]=build(m+1,r); for(int i=0;i<2;i++) if(c[m][i]) fa[c[m][i]]=m; push_up(m); return m; } int find(int x,int rank){ if(rev[x]) push_down(x); int l=c[x][0],r=c[x][1]; if(size[l]+1==rank) return x; else if(size[l]>=rank) return find(l,rank); else return find(r,rank-size[l]-1); } void rotate(int x,int &k){ int y=fa[x],z=fa[y],l=0,r=1; if(c[y][1]==x) l=1,r=0; if(y==k) k=x; else{if(c[z][0]==y) c[z][0]=x; else c[z][1]=x;} fa[x]=z; fa[y]=x; fa[c[x][r]]=y; c[y][l]=c[x][r]; c[x][r]=y; push_up(x); push_up(y); } void splay(int x,int &k){ top=0;s[++top]=x; for(int i=x;fa[i];i=fa[i]) s[++top]=fa[i]; for(int i=top;i;i--) if(rev[s[i]]) push_down(s[i]); while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if(c[z][0]==y^c[y][0]==x) rotate(y,k); else rotate(x,k); } rotate(x,k); } } int push_ans(int l,int r){ int x=find(root,l),y=find(root,r+2); splay(x,root); splay(y,c[x][1]); return pos[c[y][0]]; } void rever(int l,int r){ int x=find(root,l),y=find(root,r+2); splay(x,root); splay(y,c[x][1]); rev[c[y][0]]^=1; } int main() { n=read(); mn[0]=inf; tr[1].v=tr[n+2].v=inf; for(int i=2;i<=n+1;i++) tr[i].v=read(),tr[i].pos=i; sort(tr+2,tr+2+n,cmp); for(int i=2;i<=n+1;i++) tr[i].v=i-1; sort(tr+2,tr+2+n); for(int i=2;i<=n+1;i++) v[i]=tr[i].v; root=build(1,n+2); for(int i=1;i<=n;i++){ int x=push_ans(i,n); splay(x,root); ans[i]=size[c[x][0]]; rever(i,ans[i]); } for(int i=1;i<=n;i++){ printf("%d",ans[i]); if(i!=n) printf(" ");} return 0; }