bzoj 3506: [Cqoi2014]排序机械臂

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 110000
#define inf 0x6fffffff
int root;
struct P{
    int x,y;
    bool operator<(P a)const{
        if(x!=a.x)return x<a.x;
        return y<a.y;
    }
}val[N],mi[N];
int n,a[N];
int l[N],rev[N],pre[N],ch[N][2],siz[N];
inline void up(int x){
    if(mi[ch[x][0]]<mi[ch[x][1]]){
        l[x]=l[ch[x][0]];
        mi[x]=mi[ch[x][0]];
    }else{
        l[x]=1+l[ch[x][1]]+siz[ch[x][0]];
        mi[x]=mi[ch[x][1]];
    }
    if(val[x]<mi[x]){
        mi[x]=val[x];
        l[x]=siz[ch[x][0]]+1;
    }
    siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
inline void revs(int x){
    if(!x)return;
    rev[x]^=1;
    swap(ch[x][0],ch[x][1]);
    l[x]=siz[x]+1-l[x];
}
inline void down(int x){
    if(rev[x]){
        rev[x]=0;
        revs(ch[x][0]);
        revs(ch[x][1]);
    }   
}
void rotate(int x){
    int y=pre[x],z=pre[y];
    down(y);
    down(x);
    int k=x==ch[y][0];
    pre[ch[y][!k]=ch[x][k]]=y;
    pre[ch[x][k]=y]=x;
    pre[x]=z;
    if(z)ch[z][ch[z][1]==y]=x;
    else root=x;
    up(y);
}
void splay(int x,int f){
    int y,z;
    for(;pre[x]!=f;){
       y=pre[x],z=pre[y];
       if(z==f)rotate(x);
       else if((ch[z][1]==y)==(ch[y][1]==x))rotate(y),rotate(x);
       else rotate(x),rotate(x);        
    }
    up(x);
}
void select(int k,int f){
     int x=root;
     while(siz[ch[x][0]]+1!=k){
        down(x);
        if(k<=siz[ch[x][0]])x=ch[x][0];
        else k-=siz[ch[x][0]]+1,x=ch[x][1];  
    }
    down(x);
    splay(x,f);
}
int tot=2;
int build(int f,int L,int R){
    if(L>R)return 0;
    int x=++tot;
    int mid=(L+R)>>1;
    val[x]=(P){a[mid],mid};
    pre[x]=f;
    ch[x][0]=build(x,L,mid-1);
    ch[x][1]=build(x,mid+1,R);
    up(x);
    return x;
}
void solv(int x){
    int k=l[root];
    printf("%d ",k+x-1);
    select(1,0);
    select(k,1);
    revs(ch[ch[1][1]][0]);
    select(k-1,0);
    select(k+1,root);
    ch[ch[root][1]][0]=0;
    splay(ch[root][1],0);
}
 
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    mi[0]=(P){inf,0};
    val[1]=mi[1]=mi[0];
    val[2]=mi[2]=mi[0];
    ch[1][1]=2;
    pre[2]=1;
    root=1;
    ch[2][0]=build(2,1,n);
    up(2);
    up(1);
    for(int i=0;i<n;i++)solv(i);
}

 

posted @ 2014-05-06 16:23  wangyucheng  阅读(289)  评论(0编辑  收藏  举报