HNOI2004 宠物收养场 [Treap]

Posted zcdhj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HNOI2004 宠物收养场 [Treap]相关的知识,希望对你有一定的参考价值。

题面传送门戳我

Treap计算前驱/后继。

直接搞两个Treap,一个维护宠物,一个维护收养人。

如果输入人,并且宠物Treap不为空,直接查询一下,然后删除。否则插入人Treap。

宠物同理。

但是在查询Treap是否为空的时候不能直接写if(root[x]->size==0)因为这个时候有可能Treap为空,就会RE。

所以要这么写if(root[x]==NULL || root[x]->size==0),因为if语句有个机制,它会先判断前面的条件,如果前面的条件满足就不会去判断后面的。。。

#include <bits/stdc++.h>

const int inf=0x3f3f3f3f;
const int mod=1000000;

int N,Ans;

struct Treap
{
    Treap *ch[2];
    int r,v,size;
    Treap(int x)
    {
        v=x;
        r=rand();
        size=1;
        ch[0]=ch[1]=NULL;
    }
    int cmp(int x)
    {
        if(x==v) return -1;
        return x>v; 
    }   
    void maintain()
    {
        size=1+((ch[0]==NULL)?0:ch[0]->size)+((ch[1]==NULL)?0:ch[1]->size);
    }
}*root[2];

void rotate(Treap* &o,int d)
{
    Treap *k=o->ch[d^1];
    o->ch[d^1]=k->ch[d];
    k->ch[d]=o;
    o->maintain(),k->maintain();
    o=k;
}

void insert(Treap* &o,int x)
{
    if(o==NULL) o=new Treap(x);
    else
    {
        int d=o->cmp(x);
        insert(o->ch[d],x);
        if(o->ch[d]->r>o->r) rotate(o,d^1); 
    }
    o->maintain();
}

void remove(Treap* &o,int x)
{
    int d=o->cmp(x);
    if(d==-1)
    {
        if(o->ch[0]==NULL) o=o->ch[1];
        else if(o->ch[1]==NULL) o=o->ch[0];
        else
        {
            int d2=o->ch[0]->r>o->ch[1]->r;
            rotate(o,d2);
            remove(o->ch[d2],x);
        }
    }
    else remove(o->ch[d],x);
    if(o!=NULL) o->maintain();
}

int upper(Treap *o,int x)
{
    if(o==NULL) return -inf;
    if(o->cmp(x)<=0) return upper(o->ch[0],x);
    else return std::max(o->v,upper(o->ch[1],x));
}

int lower(Treap *o,int x)
{
    if(o==NULL) return inf;
    if(o->cmp(x)) return lower(o->ch[1],x);
    else return std::min(o->v,lower(o->ch[0],x));
} 

inline int read()
{
    register int x=0;
    register char ch=getchar();
    while(!isdigit(ch))
        ch=getchar();
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+ch-‘0‘;
        ch=getchar();
    }
    return x;
}

int main()
{
    int x,y,upp,low;
    N=read();
    for(register int i=1;i<=N;++i)
    {
        x=read(),y=read();
        if(root[x^1]==NULL || root[x^1]->size==0) insert(root[x],y);
        else
        {
            upp=upper(root[x^1],y),low=lower(root[x^1],y);
            if(upp!=-inf && low!=inf)
            {
                if(y-upp<=low-y)
                {
                    (Ans+=y-upp)%=mod;
                    remove(root[x^1],upp);
                }
                else
                {
                    (Ans+=low-y)%=mod;
                    remove(root[x^1],low);
                }
            }
            else
            {
                if(upp==-inf)
                {
                    (Ans+=low-y)%=mod;
                    remove(root[x^1],low);
                }   
                else
                {
                    (Ans+=y-upp)%=mod;
                    remove(root[x^1],upp);
                }
            } 
        }
    }
    printf("%d\n",Ans);
}

博主是蒟蒻,有错误请指出,谢谢!

以上是关于HNOI2004 宠物收养场 [Treap]的主要内容,如果未能解决你的问题,请参考以下文章

HNOI2004 宠物收养场 [Treap]

[HNOI 2004]宠物收养场

洛谷P2286 [HNOI2004]宠物收养场

1208. [HNOI2004]宠物收养场平衡树-splay

BZOJ1208: [HNOI2004]宠物收养所

HNOI2002 营业额统计 [Treap]