bzoj1552 [Cerc2007]robotic sort

题目描述:

题解:

一道非常裸的splay。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100050
inline int rd()
{
    int f = 1,c = 0;char ch = getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
    return f*c;
}
int n,p[N];
struct Pair
{
    int x,id;
}pr[N];
bool cmp(Pair a,Pair b)
{
    if(a.x!=b.x)return a.x<b.x;
    return a.id<b.id;
}
struct Splay
{
    int siz[N],fa[N],ch[N][2],rt;
    bool res[N];
    void update(int x)
    {
        siz[x] = siz[ch[x][0]]+siz[ch[x][1]]+1;
    }
    void reser(int x)
    {
        res[x]^=1;
        swap(ch[x][0],ch[x][1]);
    }
    void pushdown(int x)
    {
        if(res[x])
        {
            reser(ch[x][0]);
            reser(ch[x][1]);
            res[x]=0;
        }
    }
    int get_kth(int x,int k)
    {
        pushdown(x);
        int tmp = siz[ch[x][0]];
        if(k<=tmp)return get_kth(ch[x][0],k);
        else if(k==tmp+1)return x;
        else return get_kth(ch[x][1],k-1-tmp);
    }
    int get_rank(int x)
    {
        if(x==rt)return siz[ch[x][0]]+1;
        if(x==ch[fa[x]][0])return get_rank(fa[x])-1-siz[ch[x][1]];
        else return get_rank(fa[x])+1+siz[ch[x][0]];
    }
    int build(int l,int r,int f)
    {
        if(l>r)return 0;
        int mid = (l+r)>>1;
        int x = p[mid];
        fa[x] = f;
        ch[x][0] = build(l,mid-1,x);
        ch[x][1] = build(mid+1,r,x);
        update(x);
        return x;
    }
    void rotate(int x)
    {
        int y = fa[x],z = fa[y],k = (ch[y][1]==x);
        ch[y][k] = ch[x][!k],fa[ch[x][!k]] = y;
        ch[x][!k] = y,fa[y] = x;
        ch[z][ch[z][1]==y] = x,fa[x] = z;
        update(y),update(x);
    }
    int st[N],tl;
    void down(int x)
    {
        tl=1,st[1]=x;
        while(x)st[++tl]=x,x=fa[x];
        while(tl)pushdown(st[tl]),tl--;
    }
    void splay(int x,int goal)
    {
        down(x);
        while(fa[x]!=goal)
        {
            int y = fa[x],z = fa[y];
            if(z!=goal)
                (ch[y][1]==x)^(ch[z][1]==y)?rotate(x):rotate(y);
            rotate(x);
        }
        if(!goal)rt=x;
    }
    int deal(int x)
    {
        x++;
        down(x);
        int ret = get_rank(x);
        int rk1 = x,rk2 = ret,y;
        if(rk1>rk2)swap(rk1,rk2);
        rk1--,rk2++;
        x = get_kth(rt,rk1),y = get_kth(rt,rk2);
        splay(x,0),splay(y,x);
        reser(ch[y][0]);
        return ret-1;
    }
}tr;
int main()
{
    n=rd();
    for(int i=1;i<=n;i++)
        pr[i].x=rd(),pr[i].id=i;
    sort(pr+1,pr+1+n,cmp);
    for(int i=1;i<=n;i++)
        p[pr[i].id+1]=i+1;
    p[1]=1,p[n+2]=n+2;
    tr.rt = tr.build(1,n+2,0);
    for(int i=1;i<=n;i++)
    {
        int ans = tr.deal(i);
        printf("%d ",ans);
    }
    puts("");
    return 0;
}

 

posted @ 2018-12-22 19:30  LiGuanlin  阅读(186)  评论(0编辑  收藏  举报