【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;
}
View Code

 

posted @ 2017-06-04 21:56  Child-Single  阅读(503)  评论(0编辑  收藏  举报