Luogu P2286 [HNOI2004]宠物收养场

题意

写的比较清楚,我就不解释了。

( exttt{Data Range:}1leq nleq 8 imes 10^4)

题解

考虑对宠物和领养者分别开一棵 ( exttt{Splay}),然后就是模拟题意就行的板子题了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51,inf=0x3f3f3f3f;
ll n,op,x,res,sz,sz2,prv,nxt;
inline ll read()
{
    register ll num=0,neg=1;
    register char ch=getchar();
    while(!isdigit(ch)&&ch!='-')
    {
        ch=getchar();
    }
    if(ch=='-')
    {
        neg=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        num=(num<<3)+(num<<1)+(ch-'0');
        ch=getchar();
    }
    return num*neg;
}
namespace Splay{
    struct Node{
        ll fa,val,sz,tmp;
        ll ch[2];
        inline void reset(ll val=0,ll fa=0)
        {
            this->fa=fa,this->val=val,this->tmp=this->sz=1;
            this->ch[0]=this->ch[1]=0;
        }
    };
    struct Splay{
        ll tot,root;
        Node nd[MAXN];
        inline bool id(ll x)
        {
            return nd[nd[x].fa].ch[1]==x;
        }
        inline void update(ll x)
        {
            nd[x].sz=nd[nd[x].ch[0]].sz+nd[nd[x].ch[1]].sz+nd[x].tmp;
        }
        inline void connect(ll x,ll fa,ll dir)
        {
            nd[x].fa=fa,nd[fa].ch[dir]=x;
        }
        inline void rotate(ll x)
        {
            ll fa=nd[x].fa,gfa=nd[fa].fa,dir=id(x);
            connect(x,gfa,id(fa));
            connect(nd[x].ch[dir^1],fa,dir);
            connect(fa,x,dir^1);
            update(fa),update(x);
        }
        inline void splay(ll cur,ll target)
        {
            while(nd[cur].fa!=target)
            {
                ll fa=nd[cur].fa,gfa=nd[fa].fa;
                if(gfa!=target)
                {
                    rotate(id(cur)^id(fa)?cur:fa);
                }
                rotate(cur);
            }
            if(!target)
            {
                root=cur;
            }
        }
        inline void insert(ll val)
        {
            ll cur=root,fa=0;
            while(cur&&nd[cur].val!=val)
            {
                fa=cur,cur=nd[cur].ch[val>nd[cur].val];
            }
            if(cur)
            {
                nd[cur].tmp++;
            }
            else
            {
                cur=++tot;
                if(fa)
                {
                   nd[fa].ch[val>nd[fa].val]=cur;
                }
                nd[cur].reset(val,fa);
            }
            splay(cur,0);
        }
        inline void find(ll val)
        {
            ll cur=root;
            if(!cur)
            {
                return;
            }
            while(nd[cur].ch[val>nd[cur].val]&&val!=nd[cur].val)
            {
                cur=nd[cur].ch[val>nd[cur].val];
            }
            splay(cur,0);
        } 
        inline ll getPrev(ll val)
        {
            find(val);
            ll cur=root;
            if(nd[cur].val<val)
            {
                return cur;
            }
            cur=nd[cur].ch[0];
            while(nd[cur].ch[1])
            {
                cur=nd[cur].ch[1];
            }
            return cur;
        }
        inline ll getNext(ll val)
        {
            find(val);
            ll cur=root;
            if(nd[cur].val>val)
            {
                return cur;
            }
            cur=nd[cur].ch[1];
            while(nd[cur].ch[0])
            {
                cur=nd[cur].ch[0];
            }
            return cur;
        }
        inline ll prev(ll val)
        {
            return nd[getPrev(val)].val;
        }
        inline ll next(ll val)
        {
            return nd[getNext(val)].val;
        }
        inline void del(ll val)
        {
            ll prv=getPrev(val),nxt=getNext(val),ls;
            splay(prv,0),splay(nxt,prv),ls=nd[nxt].ch[0];
            if(nd[ls].tmp>1)
            {
                nd[ls].tmp--,splay(ls,0);   
            }
            else
            {
                nd[nxt].ch[0]=0;
            }
        }
    };
}
Splay::Splay s,s2;
int main()
{
    n=read(),s.insert(inf),s.insert(-inf);
    s2.insert(inf),s2.insert(-inf);
    for(register int i=0;i<n;i++)
    {
        op=read(),x=read();
        if(op==0)
        {
            if(sz2!=0)
            {
                prv=s2.prev(x),nxt=s2.next(x);
                prv=abs(x-prv)<=abs(x-nxt)?prv:nxt;
                res=(res+(ll)abs(x-prv))%1000000,sz2--,s2.del(prv);
            }
            else
            {
                s.insert(x),sz++;
            }
        }
        if(op==1)
        {
            if(sz!=0)
            {
                prv=s.prev(x),nxt=s.next(x);
                prv=abs(x-prv)<=abs(x-nxt)?prv:nxt;
                res=(res+(ll)abs(x-prv))%1000000,sz--,s.del(prv);
            }
            else
            {
                s2.insert(x),sz2++;
            }
        }
    }
    printf("%d
",res);
}
原文地址:https://www.cnblogs.com/Karry5307/p/13043695.html