原题有点难以描述,就不描述了,很明显的Splay(也许可以加一个离散化)
思维上最大的难点就在于如何找出下一个待排序的元素的位置
由于SPLAY数组中的元素下标是不变的
只需预处理出一个数组,储存第n个元素在SPLAY数组中的位置即可
每次把待排序元素的后继旋到根
输出(根的左子树大小-i+1)
将根的左子树翻转,待排序元素就到了SPALY的最左侧
将其删去后重复上述即可
有一个有点麻烦的地方,就是数据中可能会有重复的数
我的方法是在一开始离散化的时候,把单纯的排序,改为每个数按照原数作为第一关键字,下标为第二关键字排序即可
做起来让人感觉很难受的一道题
不过做的越难受AC得就越爽
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
char buf[5000000],*pp=buf;
#define getchar() *(pp++)
#define d(x) tr[x].d
#define s(x) tr[x].s
#define f(x) tr[x].f
#define r(x) tr[x].r
#define c(x,y) tr[x].c[y]
inline int read() {
int X=0,w=1;char ch=0;
while(ch>'9'||ch<'0')w=(ch=='-'?-1:1),ch=getchar();
while(ch<='9'&&ch>='0') X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return X*w;
}
struct node
{
int d,f,c[2],s;
bool r;
node(int _d,int _f)
{
d=_d;
f=_f;
s=1;
r=0;
c[0]=c[1]=0;
}
node(){d=f=s=r=c[0]=c[1]=0;}
}tr[200000];
int n,m,root,b[100010],pos[100010];
struct data
{
int x,y;
data(int _x=0,int _y=0)
{
x=_x;
y=_y;
}
bool inline friend operator<(data d1,data d2)
{
if(d1.x==d2.x)return d1.y<d2.y;
return d1.x<d2.x;
}
}a[100010],sorted[100010];
inline void update(int x)
{
s(x)=s(c(x,0))+s(c(x,1))+1;
}
void rotate(int x)
{
int y=f(x),z=f(y);
bool d=(c(y,0)==x);
f((c(y,d^1)=c(x,d)))=y;
f((c(x,d)=y))=x;
f(x)=z;
if(z)c(z,c(z,1)==y)=x;
update(y);
update(x);
}
inline void push_down(int x)
{
if(r(x))
{
if(c(x,0))r(c(x,0))^=1,swap(c(c(x,0),0),c(c(x,0),1));
if(c(x,1))r(c(x,1))^=1,swap(c(c(x,1),0),c(c(x,1),1));
}
r(x)=0;
}
int dfs(int l,int r,int ff)
{
if(l>r)return 0;
int mid=(l+r)/2;
int c0=dfs(l,mid-1,mid);
int c1=dfs(mid+1,r,mid);
tr[mid]=node(b[mid],ff);
pos[b[mid]]=mid;
c(mid,0)=c0;
c(mid,1)=c1;
update(mid);
return mid;
}
int st[100010],top;
void splay(int x,int rt)
{
top=0;
for(int i=x;i;i=f(i))st[++top]=i;
for(;top;top--)push_down(st[top]);
while(f(x)!=rt)
{
int y=f(x),z=f(y);
if(z!=rt)rotate(c(z,1)==y^c(y,1)==x?x:y);
rotate(x);
}
if(rt==0)root=x;
}
int main()
{
fread(buf,sizeof(char),sizeof(buf),stdin);
while(n=read())
{
memset(tr,0,sizeof(tr));
for(int i=1;i<=n;i++)
{
sorted[i]=a[i]=data(read(),i);
}
sort(sorted+1,sorted+n+1);
for(int i=1;i<=n;i++)
{
b[i]=lower_bound(sorted+1,sorted+n+1,a[i])-sorted;
}
dfs(1,n+1,0);
root=(n+1)/2;
for(int i=1;i<=n;i++)
{
splay(pos[i],0);
int x=c(root,1);
for(;c(x,0);x=c(x,0))push_down(x);
splay(x,0);
int temp=c(root,0);
printf("%d",s(temp)+i-1);
if(i!=n)printf(" ");
r(temp)^=1;
swap(c(temp,0),c(temp,1));
x=root;
for(;c(x,0);x=c(x,0))push_down(x);
splay(x,0);
root=c(root,1);
f(root)=0;
}
cout<<endl;
}
return 0;
}
/*
6
3 4 5 1 6 2
*/