bzoj 1552: [Cerc2007]robotic sort(splay)

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec   Memory Limit: 64 MB
Submit: 740   Solved: 303
[ Submit][ Status][ Discuss]

Description

bzoj 1552: [Cerc2007]robotic sort(splay)_第1张图片

Input

输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

Output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

Sample Input

6
3 4 5 1 6 2

Sample Output

4 6 4 5 6 6

HINT

Source

HNOI2009集训Day6

[ Submit][ Status][ Discuss]

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 1000003
#define inf 1000000000
using namespace std;
int n,a[N],key[N],b[N],p[N],root,sz;
int fa[N],ch[N][3],size[N],rev[N],pos[N];
int cmp(int x,int y)
{
	return a[x]<a[y]||a[x]==a[y]&&x<y;
}
int get(int x)
{
	return ch[fa[x]][1]==x;
}
void update(int x)
{
	size[x]=1;
	if (ch[x][0]) size[x]+=size[ch[x][0]];
	if (ch[x][1]) size[x]+=size[ch[x][1]];
}
void pushdown(int x)
{
	if (!rev[x])  return ;
	rev[ch[x][0]]^=1;
	rev[ch[x][1]]^=1;
	swap(ch[x][0],ch[x][1]);
	rev[x]=0;
}
void rotate(int x)
{
	pushdown(fa[x]); pushdown(x);
	int y=fa[x]; int z=fa[y]; int which=get(x);
	if (z)  ch[z][ch[z][1]==y]=x;
	fa[x]=z; fa[y]=x; ch[y][which]=ch[x][which^1];
	fa[ch[y][which]]=y; ch[x][which^1]=y;
	update(y); update(x); 
}
void splay(int x,int tar)
{
	for (int f;(f=fa[x])!=tar;rotate(x))
	 if (fa[f]!=tar)
	  rotate(get(x)==get(f)?f:x);
	if (!tar)
	 root=x;
}
int find(int x)
{
	int now=root;
	while (true)
	{
		pushdown(now);
		if (x<=size[ch[now][0]])
		 now=ch[now][0];
		else
		 {
		 	int temp=size[ch[now][0]]+1;
		 	if (temp==x)  return now;
		 	x-=temp;
		 	now=ch[now][1];
		 }
	}
}
int build(int l,int r)
{
	if(l==r)
	{
		sz++; pos[b[l]]=sz;  size[sz]=1;
		return sz;
	}
	if (l>r) return 0;
	int now=++sz; int mid=(l+r)/2; pos[b[mid]]=now;
	ch[now][0]=build(l,mid-1);
	ch[now][1]=build(mid+1,r);
	fa[ch[now][0]]=now; fa[ch[now][1]]=now; 
	size[now]=size[ch[now][0]]+size[ch[now][1]]+1;
	return now;
}
int main()
{
	freopen("a.in","r",stdin);
	freopen("my.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	 scanf("%d",&a[i]),p[i]=i;
	sort(p+1,p+n+1,cmp);
	int cnt=0;
	b[1]=0; b[n+2]=n+2;
	for (int i=1;i<=n;i++)
	 b[p[i]+1]=i;
	root=build(1,n+2);
	for (int i=1;i<=n;i++)
	 {
	    splay(pos[i],0);
	 	int ans=size[ch[root][0]];
	 	if (i!=n) printf("%d ",ans);
	 	else printf("%d\n",ans);
	 	int aa=find(i);  int bb=find(ans+2);
	 	splay(aa,0);
	 	splay(bb,aa);
	 	rev[ch[ch[root][1]][0]]^=1;
	 }
}



你可能感兴趣的:(bzoj 1552: [Cerc2007]robotic sort(splay))