这道题只需要维护一下最小值对应的位置即可。
题目大意:每次翻转[i,[i,n]中最小的数所在的位置]
暴力维护即可。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<iostream> #define inf 1000000000 #define maxn 100100 using namespace std; struct yts { int id,x; }p[maxn]; int ch[maxn][2],fa[maxn],w[maxn],mn[maxn],size[maxn]; bool tag[maxn]; int n,T,m,tot,root,a[maxn]; void reverse(int x) { tag[x]^=1; swap(ch[x][0],ch[x][1]); } void push(int x) { if (tag[x]) { if (ch[x][0]) reverse(ch[x][0]); if (ch[x][1]) reverse(ch[x][1]); tag[x]=0; } } void down(int x) { if (fa[x]) down(fa[x]); push(x); } void update(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; mn[x]=x; if (ch[x][0] && w[mn[ch[x][0]]]<w[mn[x]]) mn[x]=mn[ch[x][0]]; if (ch[x][1] && w[mn[ch[x][1]]]<w[mn[x]]) mn[x]=mn[ch[x][1]]; } int dir(int x) { return x==ch[fa[x]][1]; } void rotate(int x) { int y,z,a,b,c; y=fa[x];z=fa[y];b=dir(x);a=ch[x][!b]; if (z==0) root=x; else { c=dir(y);ch[z][c]=x; } fa[x]=z;fa[y]=x;ch[x][!b]=y;ch[y][b]=a; if (a) fa[a]=y; update(y);update(x); } void splay(int x,int i) { down(x); int y,z,b,c; while (fa[x]!=i) { y=fa[x];z=fa[y]; if (z==i) rotate(x); else { b=dir(x);c=dir(y); if (b^c) { rotate(x);rotate(x); } else { rotate(y);rotate(x); } } } } int find_k(int x,int k) { if (tag[x]) push(x); if (size[ch[x][0]]==k-1) return x; if (size[ch[x][0]]>k-1) return find_k(ch[x][0],k); else return find_k(ch[x][1],k-size[ch[x][0]]-1); } void build_tree(int l,int r,int tt) { int mid=(l+r)/2; w[tt]=a[mid]; if (l==r) {size[tt]=1;mn[tt]=tt;return;} if (l<mid) {tot++;ch[tt][0]=tot;fa[tot]=tt;build_tree(l,mid-1,tot);} if (mid<r) {tot++;ch[tt][1]=tot;fa[tot]=tt;build_tree(mid+1,r,tot);} update(tt); } int query(int x) { splay(x,0); return size[ch[x][0]]; } void bianli(int x) { if (tag[x]) push(x); if (ch[x][0]) bianli(ch[x][0]); printf("%d ",w[x]); if (ch[x][1]) bianli(ch[x][1]); } bool cmp(yts x,yts y) { return x.x<y.x || (x.x==y.x && x.id<y.id); } int main() { tot=2;root=1; fa[1]=0;size[1]=2;mn[1]=1;w[1]=inf;ch[1][1]=2; fa[2]=1;size[2]=1;mn[2]=2;w[2]=inf; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&p[i].x); p[i].id=i; } sort(p+1,p+n+1,cmp); for (int i=1;i<=n;i++) a[p[i].id]=i; tot++;ch[2][0]=tot;fa[tot]=2; build_tree(1,n,tot); update(2);update(1); for (int i=1;i<=n;i++) { int x=find_k(root,i);splay(x,0); int num=mn[ch[x][1]],rank=query(num); printf("%d",rank); if (i!=n) printf(" "); splay(x,0); int y=find_k(ch[x][1],rank-i+2); splay(y,x); reverse(ch[y][0]); } return 0; }