BZOJ 1552 [Cerc2007]robotic sort
2017.11.20
2017.11.20
给你一个序列,每次执行:选出序列中第i小的数j,之后翻转序列[i,j].
反转操作Splay最拿手……
注意每次得找到第i大的数的编号,之后提取的是这个编号+1那个数作为右端点,其他提取方法都不行……
还有这题会PE.
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 100010
struct num{int v,id;}a[N],p[N];
bool cmp(num tx,num ty) {return tx.v==ty.v?tx.id<ty.id:tx.v<ty.v;}
int n,rt,c[2][N],fa[N],siz[N];
bool rev[N];
inline void pushup(int pos) {siz[pos]=siz[c[0][pos]]+siz[c[1][pos]]+1;}
inline void pushdown(int pos)
{
if(rev[pos])
{
int tl=c[0][pos],tr=c[1][pos];
swap(c[0][tl],c[1][tl]),swap(c[0][tr],c[1][tr]);
rev[tl]^=1,rev[tr]^=1,rev[pos]=0;
}
}
inline int RI()
{
int ret=0;
char tmp=getchar();
while(tmp<'0'||tmp>'9') tmp=getchar();
while(tmp>='0'&&tmp<='9') ret=ret*10+tmp-'0',tmp=getchar();
return ret;
}
inline void rotate(int &tg,int tx)
{
int ty=fa[tx],tz=fa[ty],tl=(c[1][ty]==tx),tr=tl^1;
if(ty==tg) tg=tx;
else c[c[1][tz]==ty][tz]=tx;
fa[tx]=tz,fa[ty]=tx;
fa[c[tr][tx]]=ty,c[tl][ty]=c[tr][tx],c[tr][tx]=ty;
pushup(ty),pushup(tx);
}
inline void splay(int &tg,int tx)
{
while(tx!=tg)
{
int ty=fa[tx],tz=fa[ty];
if(ty!=tg)
{
if((c[1][ty]==tx)^(c[1][tz]==ty)) rotate(tg,tx);
else rotate(tg,ty);
}
rotate(tg,tx);
}
}
int getrank(int tg)
{
if(fa[tg])
{
int tmp=getrank(fa[tg]);
pushdown(tg);
if(c[1][fa[tg]]==tg) return tmp+siz[c[0][tg]]+1;
else return tmp-1-siz[c[1][tg]];
}
else return siz[c[0][tg]]+1;
}
int getpos(int pos,int tg)
{
pushdown(pos);
if(tg<=siz[c[0][pos]]) return getpos(c[0][pos],tg);
if(tg>siz[c[0][pos]]+1) return getpos(c[1][pos],tg-siz[c[0][pos]]-1);
return pos;
}
int build(int l,int r)
{
if(l>r) return 0;
int mid=(l+r)>>1;
c[0][mid]=build(l,mid-1),fa[c[0][mid]]=mid;
c[1][mid]=build(mid+1,r),fa[c[1][mid]]=mid;
pushup(mid);
return mid;
}
int main()
{
n=RI();
for(int i=1;i<=n;++i) a[i].v=RI(),a[i].id=i,p[i+1].v=a[i].v;
rt=build(1,n+2);
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;++i)
{
splay(rt,getpos(rt,i));
int tmp=getrank(a[i].id+1);
printf("%d%c",tmp-1,i==n?'\n':' ');
splay(c[1][rt],getpos(rt,tmp+1));
swap(c[0][c[0][c[1][rt]]],c[1][c[0][c[1][rt]]]);
rev[c[0][c[1][rt]]]^=1;
}
}