8
17
2015
0

1552: [Cerc2007]robotic sort

1552: [Cerc2007]robotic sort

Description

Input

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

Output

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),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

 

Splay

#include<cstdio>
#include<algorithm>
#define MaxN 100010
using namespace std;
int N,tot,root;
struct xx{
	int key,x,s;
}A[MaxN];
struct point{
	int key,fa,d,x,rev,mi,minn,sum;
	int son[2];
	point (){
		sum=rev=son[0]=son[1]=0;
	}
}P[MaxN];
int cmp(const xx &a,const xx &b){
	return a.key<b.key || a.key==b.key && a.x<b.x;
}
int cmp_x(const xx &a,const xx &b){
	return a.x<b.x;
}
void Down(int k){
	if (!P[k].rev) return;
    swap(P[k].son[0],P[k].son[1]);
    P[P[k].son[0]].d=0;
    P[P[k].son[1]].d=1;
    P[P[k].son[0]].rev^=1;
    P[P[k].son[1]].rev^=1;
    P[k].rev=0;
}
void Up(int k){
	P[k].mi=P[k].key; P[k].minn=k; 
	int l=P[k].son[0],r=P[k].son[1];
	P[k].sum=1+P[l].sum+P[r].sum;
	if (l&&P[l].mi<P[k].mi){
		P[k].mi=P[l].mi;
		P[k].minn=P[l].minn;
	}
	if (r&&P[r].mi<P[k].mi){
		P[k].mi=P[r].mi;
		P[k].minn=P[r].minn;
	}
}
void Turn(int x){
	int y=P[x].fa; int dx=P[x].d;
	int z=P[y].fa; int dy=P[y].d;
	P[x].fa=z; P[x].d=dy;
	if (z) P[z].son[dy]=x;
	dy=1-dx; z=P[x].son[dy];
	P[z].fa=y; P[z].d=dx; P[y].son[dx]=z;
	P[y].fa=x; P[y].d=dy; P[x].son[dy]=y;
    Up(y); Up(x);
}
void Splay(int x,int fa){
	for (;P[x].fa!=fa;){
		Down(P[P[x].fa].fa); Down(P[x].fa); Down(x);
		if (P[P[x].fa].fa!=fa){
			if (P[x].d==P[P[x].fa].d) Turn(P[x].fa);
			else Turn(x);
		}
		if (P[x].fa==fa) break;
		Turn(x);
	}
	if (!fa) root=x;
}
void Insert(int x,int key){
	int u=root;
	int fa=0;
	int d=2;
	++tot;
	for (;;){
		if (!u){
			P[tot].x=x;
			P[tot].key=key;
			P[tot].d=d;
			P[tot].fa=fa;
			P[tot].mi=key;
			P[tot].minn=tot;
			P[tot].sum=1;
			if (fa)
			    P[fa].son[d]=tot;
		    break;
		}
		if (key<P[u].mi){
			P[u].mi=key;
			P[u].minn=tot;
		}
		++P[u].sum;
	    if (x<P[u].x)d=0;
	    else d=1;
	    fa=u;
	    u=P[u].son[d];
	}
	Splay(tot,0);
}
int find(int k){
	int u=root;
	int s=0;
	for (;;){
		Down(u);
		if (P[P[u].son[0]].sum+s+1==k) return u;
		if (P[P[u].son[0]].sum+s+1>k)
		    u=P[u].son[0];
		else {
			s+=P[P[u].son[0]].sum+1;
			u=P[u].son[1];
		}
	}
}
int Min(int l,int r){
	int u1=find(l);
	int u2=find(r+2);
	Splay(u1,0);
	Splay(u2,u1);
	return P[P[u2].son[0]].minn;
}
int Sum(int u){
	Splay(u,0);
	return P[P[u].son[0]].sum+1;
}
void Rev(int l,int r){
	int u1=find(l);
	int u2=find(Sum(r)+1);
	Splay(u1,0);
	Splay(u2,u1);
	P[P[u2].son[0]].rev^=1;
}
int main(){
    scanf("%d",&N);
    for (int i=1;i<=N;++i){
        scanf("%d",&A[i].key);
        A[i].x=i;
    }
    sort(A+1,A+N+1,cmp);
    for (int i=1;i<=N;++i)
        A[i].s=i;
    sort(A+1,A+N+1,cmp_x);
    Insert(0,0);
    for (int i=1;i<=N;++i)
        Insert(i,A[i].s);
    Insert(N+1,0);
    for (int i=1;i<=N;++i){
		int k=Min(i,N);
		printf("%d",Sum(k)-1);
		if (i^N) printf(" ");
		else printf("\n");
		Rev(i,k);
    }
}
Category: BZOJ | Tags: Splay bzoj | Read Count: 640

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com