• 洛谷P3165 [CQOI2014]排序机械臂 Splay维护区间最小值


    可以将高度定义为小数,这样就完美的解决了优先级的问题。
    Code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=100000+2;
    int cnt[10000000+33];
    double B[maxn],A[maxn];
    struct Node
    {
        int s,tag;
        double v,minv;
        Node *ch[2];
        int ls(){
            if(ch[0]==NULL)return 0;
            return ch[0]->s;
        }
        Node(double u)
        {
            v=u,s=1,minv=u,tag=0;
            ch[0]=ch[1]=NULL;
        }
        int cmp(double x){
            if(ch[0]!=NULL)
            {if(ch[0]->minv==x)return 0;}
            if(ch[1]!=NULL)
            {if(ch[1]->minv==x)return 1;}
            return -1;
        }
        int cmp2(int k){
            int lsize=ch[0]==NULL?0:ch[0]->s;
            if(k<=lsize)return 0;
            if(k==lsize+1)return -1;
            return 1;
        }
        void down(){
            if(tag==1){
                tag=0;
                swap(ch[0],ch[1]);
                if(ch[0]!=NULL)ch[0]->tag=!ch[0]->tag;
                if(ch[1]!=NULL)ch[1]->tag=!ch[1]->tag;
            }
        }
        void maintain(){
            s=1,minv=v;
            if(ch[0]!=NULL){
                s+=ch[0]->s;minv=min(minv,ch[0]->minv);
            }
            if(ch[1]!=NULL){
                s+=ch[1]->s;minv=min(minv,ch[1]->minv);
            }
        }
    };
    void rotate(Node* &o,int d){
        Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
        o->maintain();k->maintain();o=k;
    }
    void splay(Node* &o,double x){
        o->down();
        int d=o->cmp(x);
        if(d!=-1){
            Node *p=o->ch[d];
            p->down();
            int d2=p->cmp(x);
            if(d2!=-1){
                splay(p->ch[d2],x);
                if(d==d2)
                    rotate(o,d^1);
                else 
                {   rotate(p,d2^1);o->ch[d]=p;}
            }
            rotate(o,d^1);
        }
    }
    void splay2(Node* &o,int k){
        o->down();
        int d=o->cmp2(k);
        if(d==1)k-=o->ls()+1;
        if(d!=-1)
        {
            Node *p=o->ch[d];
            p->down();
            int d2=p->cmp2(k);
            if(d2==1)k-=p->ls()+1;
            if(d2!=-1){
                splay2(p->ch[d2],k);
                if(d==d2)
                    rotate(o,d^1);
                else
                    rotate(o->ch[d],d2^1);
            }
            rotate(o,d^1);
        }
    }
    void build(double arr[],int l,int r,Node* &o){
        if(l>r)return;
        int mid=(l+r)/2;
        o=new Node(arr[mid]);
        build(arr,l,mid-1,o->ch[0]);
        build(arr,mid+1,r,o->ch[1]);
        o->maintain();
    }
    void remove(Node* &o){
        if(o->ch[0]==NULL)o=o->ch[1];
        else if(o->ch[1]==NULL)o=o->ch[0];
        else
        {
            Node *right=o->ch[1];
            splay2(o->ch[0],o->ch[0]->s);
            Node *left=o->ch[0];
            left->ch[1]=right;
            left->maintain();
            o=left;
        }
    }
    Node *head;
    int main()
    {
            int N;
            scanf("%d",&N);
            for(int i=1;i<=N;++i){
                int a;
                scanf("%d",&a);
                ++cnt[a];
                B[i]=a+(0.000001)*(cnt[a]);
                A[i]=B[i];
            }
            sort(B+1,B+1+N);
            build(A,1,N,head);
            for(int i=1;i<=N-1;++i)
            {
                splay(head,B[i]);
                if(head->ch[0]!=NULL)head->ch[0]->tag=!head->ch[0]->tag;
                printf("%d ",head->ls()+i);
                remove(head);
            }
            printf("%d
    ",N);
            return 0;
    }
    

      

     
  • 相关阅读:
    谈谈final, finally, finalize的区别。
    session是存储在什么地方,以什么形式存储的
    如果有几千个session,怎么提高效率
    堆和栈的区别?
    进程和线程的区别?
    Delphi中启动项管理 已安装程序卸载简单组件
    在使用TStringlist谨慎使用For循环
    Delphi 中窗体全屏组件
    TEdit扩展:做成多按钮的Edit,可用作浏览器地址栏
    Delphi 7中处理TEdit鼠标进入 离开事件
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845183.html
Copyright © 2020-2023  润新知