zoukankan      html  css  js  c++  java
  • HDU 1890 / BZOJ 3506 Robot Sort 题解

    题意:给一个初始序列,有n个数。现在要对它们进行排序。第i次通过区间翻转将第i小的数翻转到正确的位置上(即第i位),输出旋转前i的位置。

    (语死早,凑合理解一下。。)

    思路就是每次将第i小的数splay到根,统计一下再删除。答案就是左子树大小加上已删除的数的个数。

    然后这题是有可能出现重复的数字的。。有重复的话在前面的比较小。(这点我调了1h

    #include<cstdio>
    #include<algorithm>
    const int MAXN=100000+10;
    const int INF=~0U>>1;
    int a[MAXN];
    struct Node{
        int s,v;
        bool rev;
        Node* p,*ch[2],*minn;
        Node() {s=rev=0;v=INF;minn=this;}
        inline bool d() {return p->ch[1]==this;}
        inline void maintain();
        inline void revIt()
        {
            std::swap(ch[0],ch[1]);
            rev^=1;
        }
        inline void setc(Node* t,bool d)
        {
            ch[d]=t;
            t->p=this;
        }
        inline void pushdown();
    }Tnull,*null=&Tnull;
    Node mem[MAXN],*C=mem;
    Node* root;
    struct met{
        Node* temp;
        int pos;
        bool operator<(const met& rhs)const
        {
            return temp->v < rhs.temp->v ||(rhs.temp->v == temp->v && pos<rhs.pos);
        }
    }h[MAXN];
    inline Node* Min(Node* a,Node* b)
    {
        return a->v <= b->v ?a:b;
    }
    inline void Node::pushdown()
    {
        if(rev)
        {
            if(ch[0]!=null) ch[0]->revIt();
            if(ch[1]!=null) ch[1]->revIt();
            rev=0;
        }
    }
    inline void Node::maintain()
    {
        s=ch[0]->s+ch[1]->s+1;
        minn=Min(Min(ch[0]->minn,this),ch[1]->minn);
    }
    inline void init()
    {
        C=mem;
    }
    inline Node* NewNode(int v)
    {
        C->v=v;C->s=1;
        C->ch[0]=C->ch[1]=null;
        return C++;
    }
    Node* build(int l,int r) //[l,r)
    {
        if(l>=r) return null;
        int m=l+r>>1;
        Node* t=NewNode(a[m]);
        h[m].temp=t;h[m].pos=m;
        Node* L=build(l,m),*R=build(m+1,r);
        t->setc(L,0);t->setc(R,1);
        t->maintain();
        return t;
    }
    void rot(Node* t)
    {
        Node* p=t->p;
        p->pushdown();t->pushdown();
        int d=t->d();
        p->p->setc(t,p->d());
        p->setc(t->ch[d^1],d);
        t->setc(p,d^1);
        p->maintain();
        if(p==root) root=t;
    }
    void splay(Node* t,Node* f=null)
    {
        while(t->p!=f)
        {
            if(t->p->p==f) rot(t);
            else
                t->d()==t->p->d()?(rot(t->p),rot(t)):(rot(t),rot(t));
        }
        t->maintain();
    }
    Node* select(int k)
    {
        for(Node* t=root;;)
        {
            t->pushdown();
            int s=t->ch[0]->s;
            if(k==s) return t;
            if(k>s) k-=s+1,t=t->ch[1];
            else t=t->ch[0];
        }
    }
    inline void splay(int k,Node* f=null)
    {
        splay(select(k),f);
    }
    Node*& get(int l,int r)
    {
        Node* L=select(l-1);
        Node* R=select(r);
        splay(L);
        splay(R,L);
        return R->ch[0];
    }
    int DelMin(int i)
    {
        splay(h[i].temp);
        int s=root->ch[0]->s;
        Node*& t=get(1,s);
        t->revIt();
        splay(s-1);
        splay(s+1,root);
        root->ch[1]->ch[0]=null;
        root->ch[1]->maintain();
        root->maintain();
        return s;
    }
    int n;
    int main()
    {
        while(scanf("%d",&n)!=EOF && n)
        {
            a[0]=a[n+1]=INF;
            init();
            for(int i=1;i<=n;++i) scanf("%d",a+i);
            root=build(0,n+2);
            root->p=null;
            std::sort(h+1,h+n+1);
            for(int i=0;i<n;++i)
            {
                printf("%d%c",DelMin(i+1)+i,i==n-1?'
    ':' ');
            }
        }
        return 0;
    }
  • 相关阅读:
    compass 制作css sprites
    net模块
    javascript -- 代理模式
    javascript -- 单例模式
    js 对象的浅拷贝和深拷贝
    js 对象的封装,继承,多态的理解
    this,call,apply
    flex 实现圣杯布局
    ubuntu中安装mongodb
    devDependencies和dependencies的区别
  • 原文地址:https://www.cnblogs.com/lowsfish/p/4343368.html
Copyright © 2011-2022 走看看