1552: [Cerc2007]robotic sort
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 681 Solved: 278
[ Submit][ Status][ Discuss]
Description

Input
Output
Sample Input
3 4 5 1 6 2
Sample Output
4 6 4 5 6 6
解题思路:splay的裸题,每个点记入下它子树的最小值,然后splay维护翻转和选择区间
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,sum,ug,mx,root;
int a[110000];
int zhi[110000],dui[110000],pan[110000],qo[110000],size[110000],fa[110000],l[110000],r[110000],rever[110000];
int po[110000],q[110000];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
void build(int &x,int lg,int rg,int f)
{
int mid=(lg+rg)/2;
x=mid;
zhi[mid]=a[mid]; dui[mid]=mid; pan[mid]=mid; qo[mid]=zhi[mid]; size[mid]=rg-lg+1; fa[mid]=f;
if (lg==rg) return;
if (lg<=mid-1) build(l[x],lg,mid-1,mid);
if (mid+1<=rg) build(r[x],mid+1,rg,mid);
int u; if (qo[l[x]]<qo[r[x]]||(qo[l[x]]==qo[r[x]] && dui[pan[l[x]]]<dui[pan[r[x]]])){u=pan[l[x]];}else u=pan[r[x]];
if (qo[u]<qo[pan[mid]] || (qo[u]==qo[pan[mid]] && dui[u]<dui[pan[mid]]))
{
pan[mid]=u; qo[mid]=qo[u];
}
}
void pushdown(int now)
{
if (rever[now]==1)
{
rever[now]^=1;
if (l[now]!=0) rever[l[now]]^=1;
if (r[now]!=0) rever[r[now]]^=1;
swap(l[now],r[now]);
}
}
void find(int now,int zhi)
{
pushdown(now);
if (zhi==now)
{
sum+=size[l[now]]+1;
return;
}
if (pan[l[now]]==zhi)
{
find(l[now],zhi);
}else
{
sum+=size[l[now]]+1;
find(r[now],zhi);
}
}
int find1(int now,int sug)
{
pushdown(now);
if (sug==size[l[now]]+1) return now;
if (sug>size[l[now]]+1) return find1(r[now],sug-size[l[now]]-1);else return find1(l[now],sug);
}
void maindown(int now)
{
size[now]=size[l[now]]+size[r[now]]+1;
pan[now]=now; qo[now]=zhi[now];
int u; if (qo[pan[l[now]]]<qo[pan[r[now]]]||(qo[pan[l[now]]]==qo[pan[r[now]]] && dui[pan[l[now]]]<dui[pan[r[now]]])){u=pan[l[now]];}else u=pan[r[now]];
if (qo[u]<qo[pan[now]] || (qo[u]==qo[pan[now]] && dui[u]<dui[pan[now]]))
{
pan[now]=u; qo[now]=qo[u];
}
}
void rotate(int x,int &mu)
{
int y=fa[x]; int z=fa[y];
if (y==mu) mu=x;else
{
if (l[z]==y) l[z]=x; else r[z]=x;
}
fa[y]=x; fa[x]=z;
if (l[y]==x)
{
fa[r[x]]=y; l[y]=r[x]; r[x]=y;
}else
{
fa[l[x]]=y; r[y]=l[x]; l[x]=y;
}
maindown(y); maindown(x);
}
void splay(int x,int &mu)
{
int now=x; int tail=0;
while(now!=mu)
{
++tail; q[tail]=now; now=fa[now];
} pushdown(now);
for (int i=tail;i>=1;--i) pushdown(q[i]);
while (x!=mu)
{
int y=fa[x]; int z=fa[y];
if (y!=mu)
{
if (l[y]==x ^ l[z]==y) rotate(x,mu);else
rotate(y,mu);
}
rotate(x,mu);
}
}
int main()
{
n=read(); a[1]=0x7fffffff; a[n+2]=0x7fffffff; a[0]=0x7fffffff; qo[0]=0x7fffffff;
for (int i=1;i<=n;++i)
{
a[i+1]=read();
}
n=n+2;
build(root,1,n,0);
for (int i=1;i<=n-2;++i)
{
if (i==n-2)
{
printf("%d",n-2);
return(0);
}
ug=find1(root,i);
splay(ug,root);
sum=0;
find(root,pan[r[root]]); ug=find1(root,sum+1);
printf("%d ",sum-1);
splay(ug,r[root]);
splay(pan[r[root]],l[r[root]]);
rever[l[r[root]]]^=1;
}
}