这道题只需要维护一下最小值对应的位置即可。
题目大意:每次翻转[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;
}