zoukankan      html  css  js  c++  java
  • bzoj:1208: [HNOI2004]宠物收养所

    Description

    最近,阿Q开了一间宠物收养所。收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物。每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值。这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少。 1. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值为a,那么它将会领养一只目前未被领养的宠物中特点值最接近a的一只宠物。(任何两只宠物的特点值都不可能是相同的,任何两个领养者的希望领养宠物的特点值也不可能是一样的)如果有两只满足要求的宠物,即存在两只宠物他们的特点值分别为a-b和a+b,那么领养者将会领养特点值为a-b的那只宠物。 2. 收养宠物的人过多,假若到来一只被收养的宠物,那么哪个领养者能够领养它呢?能够领养它的领养者,是那个希望被领养宠物的特点值最接近该宠物特点值的领养者,如果该宠物的特点值为a,存在两个领养者他们希望领养宠物的特点值分别为a-b和a+b,那么特点值为a-b的那个领养者将成功领养该宠物。 一个领养者领养了一个特点值为a的宠物,而它本身希望领养的宠物的特点值为b,那么这个领养者的不满意程度为abs(a-b)。【任务描述】你得到了一年当中,领养者和被收养宠物到来收养所的情况,希望你计算所有收养了宠物的领养者的不满意程度的总和。这一年初始时,收养所里面既没有宠物,也没有领养者。

    Input

    第一行为一个正整数n,n<=80000,表示一年当中来到收养所的宠物和领养者的总数。接下来的n行,按到来时间的先后顺序描述了一年当中来到收养所的宠物和领养者的情况。每行有两个正整数a, b,其中a=0表示宠物,a=1表示领养者,b表示宠物的特点值或是领养者希望领养宠物的特点值。(同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个)

    Output

    仅有一个正整数,表示一年当中所有收养了宠物的领养者的不满意程度的总和mod 1000000以后的结果。

    Sample Input

    5
    0 2
    0 4
    1 3
    1 2
    1 5

    Sample Output

    3
     
     
    TREAP
    调了好久……对拍技能get……
     
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    int n,l,w,ans,qa,qi,o,p,nu=0;
    inline int read(){
        p=0;o=getchar();
        while(o<'0'||o>'9') o=getchar();
        while(o>='0'&&o<='9') p=p*10+o-48,o=getchar();
        return p;
    }
    struct tree{
        int l,r,k,ra,w,f;
        tree(){
            f=l=r=-1;
        }
    };
    struct treap{
        int size,root;
        tree t[80001];
        treap(){
            size=0;root=-1;
        }
        inline void ler(int &p){
            int k=t[p].r;
            t[k].f=t[p].f;
            t[p].f=k;
            if (t[k].l!=-1) t[t[k].l].f=p;
            t[p].r=t[k].l;
            t[k].l=p;
            p=k;
        }
        inline void rir(int &p){
            int k=t[p].l;
            t[k].f=t[p].f;
            t[p].f=k;
            if (t[k].r!=-1) t[t[k].r].f=p;
            t[p].l=t[k].r;
            t[k].r=p;
            p=k;
        }
        inline void insert(int &p,int k,int f){
            if (p==-1){
                p=++size;
                t[p].k=k;
                t[p].w=1;
                t[p].f=f;
                t[p].ra=rand();
                return;
            }
            if (t[p].k==k) t[p].w++;else
            if (t[p].k>k){
                insert(t[p].l,k,p);
                if (t[t[p].l].ra<t[p].ra) rir(p);
            }else{
                insert(t[p].r,k,p);
                if (t[t[p].r].ra<t[p].ra) ler(p);
            }
        }
        inline void dell(int &p){
            if (t[p].l==-1&&t[p].r==-1) p=-1;else
            if (t[p].l==-1) ler(p),dell(t[p].l);else
            if (t[p].r==-1) rir(p),dell(t[p].r);else
            if (t[t[p].l].ra<t[t[p].r].ra) rir(p),dell(t[p].r);else ler(p),dell(t[p].l);
        }
        inline void del(int p){
            t[p].w--;
            if (t[p].w) return;
            if (root==p) dell(root);else
            if (t[t[p].f].l==p) dell(t[t[p].f].l);else dell(t[t[p].f].r);
        }
        inline int qua(int p,int k){
            if (p==-1) return p=-1;
            if (t[p].k==k) return p;else
            if (t[p].k<k) return qua(t[p].r,k);else{
                int u=qua(t[p].l,k);
                if (u==-1) return p;else return u;
            }
        }
        inline int qui(int p,int k){
            if (p==-1) return -1;
            if (t[p].k==k) return p;else
            if (t[p].k>k) return qui(t[p].l,k);else{
                int u=qui(t[p].r,k);
                if (u==-1) return p;else return u;
            }
        }
    };
    treap an,pe;
    int main(){
        n=read();
        while(n--){
            l=read();w=read();
            if (l){
                if (nu>=0) pe.insert(pe.root,w,-1);else{
                    qa=an.qua(an.root,w);qi=an.qui(an.root,w);
                    if (qi==-1) ans+=an.t[qa].k-w,an.del(qa);else
                    if (qa==-1) ans+=w-an.t[qi].k,an.del(qi);else
                    if (w-an.t[qi].k<=an.t[qa].k-w) ans+=w-an.t[qi].k,an.del(qi);else ans+=an.t[qa].k-w,an.del(qa);
                }
                nu++;
            }else{
                if (nu<=0) an.insert(an.root,w,-1);else{
                    qa=pe.qua(pe.root,w);qi=pe.qui(pe.root,w);
                    if (qi==-1) ans+=pe.t[qa].k-w,pe.del(qa);else
                    if (qa==-1) ans+=w-pe.t[qi].k,pe.del(qi);else
                    if (w-pe.t[qi].k<=pe.t[qa].k-w) ans+=w-pe.t[qi].k,pe.del(qi);else ans+=pe.t[qa].k-w,pe.del(qa);
                }
                nu--;
            }
            if (ans>=1000000) ans%=1000000;
        }
        printf("%d
    ",ans);
    }
  • 相关阅读:
    状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely
    简单几何(推公式) UVA 11646 Athletics Track
    简单几何(四边形形状) UVA 11800 Determine the Shape
    简单几何(求交点) UVA 11437 Triangle Fun
    计算几何模板
    简单几何(相对运动距离最值) UVA 11796 Dog Distance
    简单几何(求划分区域) LA 3263 That Nice Euler Circuit
    覆盖的面积 HDU
    Desert King 最小比率生成树 (好题)
    约会安排 (区间合并)毒瘤题
  • 原文地址:https://www.cnblogs.com/Enceladus/p/5179530.html
Copyright © 2011-2022 走看看