【bzoj1208】宠物收养所——treap

第二道treap题,码完之后总是RE……查了两个多小时的错,对拍了三四份代码啊啊啊

刚开始发现if(tree[k].l*tree[k].r==0)k=tree[k].l+tree[k].r;这一句写错了,但改完还是WA或RE……

于是又找了接近两个小时的错啊啊啊,终于发现是左旋操作中的一个t打成了k,枉我之前还一直以为是del或者get_big写错了呢

还是不够细心啊

好了,言归正传。

这道题由于题目说“同一时间呆在收养所中的,要么全是宠物,要么全是领养者”,那么就可以建一棵treap树(用一个变量ty储存当前树类型,即1或0),与当前树类型相同就加入该节点,不同就对比该值与前驱值差和后继值差的绝对值,取较小的一个(若相同则选前驱),接着ans加上该值(记得要取余mod!),然后del前驱或后继,最后得到的ans即为答案。

具体细节看代码。

#include<cstdio>
#include<cstdlib>
#include<iostream>
const int mod=1000000;
using namespace std;
int n,root=0,ty,ans=0,size=0,tt,pp,a,b;
struct point
{
    int v,l,rnd,r;
}tree[100002];
void lturn(int &k)
{
    int t=tree[k].r;
    tree[k].r=tree[t].l;
    tree[t].l=k;
    k=t;
}
void rturn(int &k)
{
    int t=tree[k].l;
    tree[k].l=tree[t].r;
    tree[t].r=k;
    k=t;
}
void insert(int &k,int x)
{
    if(k==0)
    {
        size++;k=size;
        tree[k].l=tree[k].r=0;
        tree[k].v=x;tree[k].rnd=rand();
        return;
    }
    if(x>tree[k].v)
    {
        insert(tree[k].r,x);
        if(tree[tree[k].r].rnd<tree[k].rnd)lturn(k);
    }
    else
    {
        insert(tree[k].l,x);
        if(tree[tree[k].l].rnd<tree[k].rnd)rturn(k);
    }
}
void del(int &k,int x)
{
    if(k==0)return;
    if(tree[k].v==x)
    {
        if(tree[k].l*tree[k].r==0)k=tree[k].l+tree[k].r;
        else if(tree[tree[k].l].rnd<tree[tree[k].r].rnd)rturn(k),del(k,x);
        else lturn(k),del(k,x);
    }
    else if(tree[k].v<x)del(tree[k].r,x);
    else del(tree[k].l,x);
}
void get_big(int k,int x)
{
    if(k==0)return;
    if(tree[k].v<=x)
    {
        tt=k;get_big(tree[k].r,x);
    }
    else get_big(tree[k].l,x);
}
void get_small(int k,int x)
{
    if(k==0){return;}
    if(tree[k].v>x)
    {
        pp=k;get_small(tree[k].l,x);
    }
    else get_small(tree[k].r,x);
}
int main()
{
    int num=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&a,&b);
        if(!num){size=0;root=0,insert(root,b),ty=a,num++;}
        else if(a==ty){
            insert(root,b);
            num++;
        }
        else
        {
            tt=0;get_big(root,b);
            pp=0;get_small(root,b);
            if(!pp||(tt&&tree[tt].v&&b-tree[tt].v<=tree[pp].v-b)){ans=(ans+b-tree[tt].v)%mod;del(root,tree[tt].v);}
            else {ans=(ans+tree[pp].v-b)%mod;del(root,tree[pp].v);}
            num--;
        }
    }
    printf("%d",ans);
    return 0;
}

时间: 2024-07-28 13:47:56

【bzoj1208】宠物收养所——treap的相关文章

bzoj1208 宠物收养所treap/splay/set

偷懒用set 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<set> 5 #include<algorithm> 6 #define rep(i,l,r) for(int i=l;i<r;i++) 7 #define update(a) (ans+=a)%=1000000 8 typedef long long ll; 9 using names

宠物收养场 Treap

宠物收养场 时间限制: 1 Sec  内存限制: 128 MB 题目描述 凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养场的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养场总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少.

[HNOI2004]宠物收养场——treap

凡凡开了一间宠物收养场.收养场提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物. 每个领养者都希望领养到自己满意的宠物,凡凡根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养场的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养场总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 被遗弃的宠物过多时,假若到来一个领养者,这个领养者希望领养的宠物的特点值

BZOJ_1208Codevs_1258_[HNOI2004]_宠物收养所(Treap/Splay)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1208 (据说codevs要更新?就不放codevs的地址了吧...) 有宠物和人,每个单位都有一个与其他单位不同的值(正),如果现在有宠物,来了一个人,人取走和他的值最接近的宠物(如果有两个选值小的),如果现在有人,来了一个宠物,和它值最接近的人(如果有两个选值小的)取走它.求每次带宠物走两个单位的值的差的绝对值的总和. 分析 用平衡树查找前驱和后驱即可.依照题意,要么全是人要么全是宠物,所

HNOI2004 宠物收养场 [Treap]

题面传送门戳我 Treap计算前驱/后继. 直接搞两个Treap,一个维护宠物,一个维护收养人. 如果输入人,并且宠物Treap不为空,直接查询一下,然后删除.否则插入人Treap. 宠物同理. 但是在查询Treap是否为空的时候不能直接写if(root[x]->size==0)因为这个时候有可能Treap为空,就会RE. 所以要这么写if(root[x]==NULL || root[x]->size==0),因为if语句有个机制,它会先判断前面的条件,如果前面的条件满足就不会去判断后面的..

BZOJ1208: [HNOI2004]宠物收养所 平衡树 Treap 模板题

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被 主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希 望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程 了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个

[bzoj1208][HNOI2004][宠物收养所] (平衡树)

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领养者

[bzoj1208][HNOI2004]宠物收养所

题目好长啊直接copy算了 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领

宠物收养所(bzoj1208)

Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特殊的公式,得出该领养者希望领养的宠物的特点值a(a是一个正整数,a<2^31),而他也给每个处在收养所的宠物一个特点值.这样他就能够很方便的处理整个领养宠物的过程了,宠物收养所总是会有两种情况发生:被遗弃的宠物过多或者是想要收养宠物的人太多,而宠物太少. 1. 被遗弃的宠物过多时,假若到来一个领养者