题意:n个数排成一列,每次选择序列中的最小值(如有多个,取原始位置最小的),把它和它前面的所有数翻转,然后把这个数从序列中删去。输出每次选择的最小值的下标。
思路:用数组原下标建树,然后排序,将小的排在前面,只要按照顺序将这数的下标翻转到根节点,他的左子树加上自己就是他要的答案,然后删点。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node
{
int num,id;
}a[N];
int sz,root;
int key[N],ch[N][2],f[N],size[N],lazy[N];
bool get(int x)
{
return ch[f[x]][1]==x;
}
void pushup(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void pushdown(int x)
{
if(lazy[x])
{
lazy[ch[x][0]]^=1;
lazy[ch[x][1]]^=1;
lazy[x]=0;
swap(ch[x][0],ch[x][1]);
}
}
bool cmp(node a,node b)
{
if(a.num!=b.num)return a.num<b.num;
return a.id<b.id;
}
void rotate(int x)
{
int old=f[x],oldf=f[old],whichx=get(x);
ch[old][whichx]=ch[x][whichx^1];
f[ch[old][whichx]]=old;
ch[x][whichx^1]=old;
f[old]=x;
f[x]=oldf;
if(oldf)
ch[oldf][ch[oldf][1]==old]=x;
pushup(old);
pushup(x);
}
void splay(int x,int goal)
{
int y,z;
pushdown(x);
while(f[x] != goal)
{
y = f[x],z = f[y];
if(z == goal)
{
pushdown(y);
pushdown(x);
rotate(x);
}
else
{
pushdown(z);
pushdown(y);
pushdown(x);
if((ch[z][0]==y) == (ch[y][0]==x)) rotate(y);
else rotate(x);
}
}
if(goal == 0) root = x;
}
int pre()
{
int now=ch[root][0];
pushdown(now);
while(ch[now][1])
{
now=ch[now][1];
pushdown(now);
}
return now;
}
int build(int l,int r,int x)
{
if(l>r)return 0;
int mid=(l+r)/2;
int now=mid;
f[now]=x;
size[now]=1;
ch[now][0]=build(l,mid-1,now);
ch[now][1]=build(mid+1,r,now);
pushup(now);
return now;
}
void del()
{
if(!ch[root][0])
{
root=ch[root][1];
f[root]=0;
return ;
}
else if(!ch[root][1])
{
root=ch[root][0];
f[root]=0;
return ;
}
int x=pre();
splay(x,root);
ch[x][1]=ch[root][1];
f[ch[root][1]]=x;
root=x;
f[root]=0;
pushup(root);
return;
}
void init()
{
root=0;
memset(size,0,sizeof(size));
memset(lazy,0,sizeof(lazy));
memset(ch,0,sizeof(ch));
memset(f,0,sizeof(f));
}
int main()
{
int n;
while(~scanf("%d",&n)&&n)
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].num);
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
root=build(1,n,0);
for(int i = 1; i <=n; i++)
{
splay(a[i].id,0);
lazy[ch[root][0]] ^= 1;
if(i>1)printf(" ");
printf("%d",i+size[ch[root][0]]);
del();
}
printf("\n");
}
return 0;
}