bzoj 1552: [Cerc2007]robotic sort

1552: [Cerc2007]robotic sort

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1198  Solved: 457
[Submit][Status][Discuss]

Description

bzoj 1552: [Cerc2007]robotic sort

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

splay区间反转
#include<cstdio>
#include<algorithm>
using namespace std;
#define INF 0x7fffffff
int n;
const int maxn = ;
struct Data{
int a,pos;
bool operator < (const Data & q)const {
if(q.a==a)return pos<q.pos;
else return a<q.a;
}
}l[maxn];
int mn[maxn],size[maxn],root,data[maxn],ch[maxn][],mnpos[maxn];
int rev[maxn],fa[maxn];
inline void pushdown(int x)
{
rev[x]=;
rev[ch[x][]]^=;
rev[ch[x][]]^=;
swap(ch[ch[x][]][],ch[ch[x][]][]);
swap(ch[ch[x][]][],ch[ch[x][]][]);
}
inline void pushup(int x)
{
mn[x]=min(data[x],min(mn[ch[x][]],mn[ch[x][]]));
if(mn[x]==data[x])mnpos[x]=x;
else if(mn[x]==mn[ch[x][]])mnpos[x]=mnpos[ch[x][]];
else mnpos[x]=mnpos[ch[x][]];
size[x]=size[ch[x][]]+size[ch[x][]]+;
}
inline int getkth(int k,int rt)
{
if(rev[rt])pushdown(rt);
if(k==size[ch[rt][]]+)return rt;
if(k<size[ch[rt][]]+)return getkth(k,ch[rt][]);
else getkth(k-size[ch[rt][]]-,ch[rt][]);
} inline int son(int x){
return ch[fa[x]][]==x;
}
void rotate(int x)
{
int y=fa[x],z=fa[y],b=son(x),c=son(y),a=ch[x][!b];
if(z)ch[z][c]=x;else root=x;fa[x]=z;
if(a)fa[a]=y;ch[y][b]=a;
ch[x][!b]=y;fa[y]=x;
pushup(y),pushup(x);
}
void splay(int &x,int i) {
while(fa[x]!=i)
{
int y=fa[x],z=fa[y];
if(z==i){
rotate(x);
}else {
if(rev[z])pushdown(z);if(rev[y])pushdown(y);if(rev[x])pushdown(x);
if(son(x)==son(y)) {
rotate(y),rotate(x);
}
else {
rotate(x);rotate(x);
}
}
}
}
int getmnpos(int l,int r)
{
int ll=getkth(l-,root);
int rr=getkth(r+,root);
splay(ll,);
splay(rr,ll);
return mnpos[ch[rr][]];
}
inline void reverse(int l,int r)
{
int ll=getkth(l-,root),rr=getkth(r+,root),p;
splay(ll,);splay(rr,ll);
p=ch[rr][];rev[p]^=;
swap(ch[p][],ch[p][]);
}
int main() {
scanf("%d",&n);
for(int i=;i<=n+;i++) scanf("%d",&l[i].a),l[i].pos=i;
sort(l+,l+n+);
for(int i=;i<=n+;i++)data[l[i].pos]=i;
for(int i=;i<=n+;i++)mn[i]=INF;
data[]=data[]=data[n+]=INF;root=;
for(int i=;i<=n+;i++) {
fa[i]=i-;
ch[i][]=i+;
}
ch[n+][]=;
for(int i=n+;i>=;i--) {
pushup(i);
}
for(int i=;i<=n;i++)
{
int po=getmnpos(i+,n+);
splay(po,);
printf("%d",size[ch[po][]]);
reverse(i+,size[ch[po][]]+);
if(i!=n)printf(" ");
}
return ;
}
上一篇:BZOJ 1552: [Cerc2007]robotic sort( splay )


下一篇:[BZOJ3506] [Cqoi2014] 排序机械臂 (splay)