Robotic Sort HDU - 1890

http://acm.hdu.edu.cn/showproblem.php?pid=1890

伸展树模板

博客:

https://www.cnblogs.com/wxgblogs/p/5506234.html

https://blog.csdn.net/wr132/article/details/50599747

http://www.cnblogs.com/vamei/archive/2013/03/21/2964092.html

#include <bits/stdc++.h>
using namespace std;

struct Node;
Node* null;

struct Node
{
    Node *ch[2],*fa;
    int size,rev;
    Node()
    {
        ch[0]=ch[1]=fa=null;
        rev=0;
    }
    inline void setc(Node* p,int d)
    {
        ch[d]=p;
        p->fa=this;
    }
    inline bool d()
    {
        return fa->ch[1]==this;
    }
    void clear()
    {
        fa=ch[0]=ch[1]=null;
        size=1,rev=0;
    }
    void update_rev()
    {
        if(this==null) return;
        swap(ch[0],ch[1]);
        rev^=1;
    }
    inline void pushup()
    {
        if(this==null) return;
        size=ch[0]->size+ch[1]->size+1;
    }
    inline void pushdown()
    {
        if(this==null) return;
        if(rev!=0)
        {
            ch[0]->update_rev();
            ch[1]->update_rev();
            rev=0;
        }
    }
    inline bool isroot()
    {
        return fa==null||(this!=fa->ch[0]&&this!=fa->ch[1]);
    }
};

Node *node[100010];
Node pool[100010];
Node *root,*tail;
int a[100010],b[100010];
int n;

inline void rotate(Node *x)
{
    Node *f,*ff;
    int c,cc;
    f=x->fa,ff=x->fa->fa;
    f->pushdown();
    x->pushdown();
    c=x->d(),cc=f->d();
    f->setc(x->ch[!c],c);
    x->setc(f,!c);
    if(ff->ch[cc]==f) ff->setc(x,cc);
    else x->fa=ff;
    f->pushup();
}

inline void splay(Node *&root,Node *x,Node *goal)
{
    while(x->fa!=goal)
    {
        if(x->fa->fa==goal) rotate(x);
        else
        {
            x->fa->fa->pushdown();
            x->fa->pushdown();
            x->pushdown();
            if(x->d()==x->fa->d()) rotate(x->fa);
            else rotate(x);
            rotate(x);
        }
    }
    x->pushup();
    if(goal==null) root=x;
}

Node *get_kth(Node *r,int k)
{
    Node *x=r;
    x->pushdown();
    while(x->ch[0]->size+1!=k)
    {
        if(x->ch[0]->size+1>k)
        {
            x=x->ch[0];
        }
        else
        {
            k-=(x->ch[0]->size+1);
            x=x->ch[1];
        }
        x->pushdown();
    }
    return x;
}

Node *get_next(Node *p)
{
    p->pushdown();
    p=p->ch[1];
    p->pushdown();
    while(p->ch[0]!=null)
    {
        p=p->ch[0];
        p->pushdown();
    }
    return p;
}

void build(Node *&x,int l,int r,Node *fa)
{
    int m;
    if(l>r) return;
    m=(l+r)/2;
    x=tail++;
    x->clear();
    x->fa=fa;
    node[m]=x;
    build(x->ch[0],l,m-1,x);
    build(x->ch[1],m+1,r,x);
    x->pushup();
}

void init(int n)
{
    Node* p;
    int i;
    tail=pool;
    null=tail++;
    null->fa=null->ch[0]=null->ch[1]=null;
    null->size=0,null->rev=0;
    p=tail++;
    p->clear();
    root=p;
    p=tail++;
    p->clear();
    root->setc(p,1);
    build(root->ch[1]->ch[0],1,n,root->ch[1]);
    root->ch[1]->pushup();
    root->pushup();
}

bool cmp(int i,int j)
{
    if(a[i]!=a[j]) return a[i]<a[j];
    else return i<j;
}

int main()
{
    int i,sz;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=i;
        }
        init(n);
        sort(b+1,b+n+1,cmp);
        for(i=1;i<=n;i++)
        {
            splay(root,node[b[i]],null);
            sz=root->ch[0]->size;
            printf("%d",sz);
            if(i==n) printf("\n");
            else printf(" ");
            splay(root,get_kth(root,i),null);
            splay(root,get_kth(root,sz+2),root);
            root->ch[1]->ch[0]->update_rev();
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/81158251