[BZOJ 1208] 宠物收养所

Link:

BZOJ 1208 传送门

Solution:

求前驱后继,很明显的平衡树操作

其实$set$完全可以做,主要是为了复习下$Treap$结果调了好久……

注意:在写平衡树删除时一定要记得考虑删除数不存在的情况

特别是$Treap$,如果访问到空要直接返回否则死循环……

Code:

#include <bits/stdc++.h>
 
using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef pair<int,int> P;
typedef double db;
const int MAXN=1e5+10,MOD=1e6,INF=1<<30;
 
namespace Treap
{
    int tot,rt;
    int sz[MAXN],pri[MAXN],val[MAXN],s[MAXN][2];
     
    void Pushup(int x)
    {sz[x]=sz[s[x][0]]+sz[s[x][1]]+1;}
    void Rotate(int &x,int f)
    {//注意这里的旋转 
        int tmp=s[x][f];
        s[x][f]=s[tmp][f^1];s[tmp][f^1]=x;
        Pushup(x);Pushup(x=tmp);
    }
    void Insert(int &x,int k)
    {
        if(!x)
        {
            x=++tot;
            pri[x]=rand();val[x]=k;
            sz[x]=1;return;
        }
         
        int nxt=k>val[x];Insert(s[x][nxt],k);
        if(pri[x]>pri[s[x][nxt]]) Rotate(x,nxt);
        Pushup(x);
    }
    int Pre(int &x,int k)
    {
        if(!x) return -INF;
        if(k==val[x]) return val[x];
        if(k>val[x]) return max(val[x],Pre(s[x][1],k));
        else return Pre(s[x][0],k); 
    }
    int Nxt(int &x,int k)
    {
        if(!x) return INF;
        if(k==val[x]) return val[x];
        if(k<val[x]) return min(val[x],Nxt(s[x][0],k));
        else return Nxt(s[x][1],k);
    }
    void Del(int &x,int k)
    {
        if(!x) return;//防止k不存在! 
        if(val[x]==k)
        {
            if(s[x][0]*s[x][1]==0)
            {x=s[x][0]+s[x][1];return;}
            int nxt=pri[s[x][0]]<pri[s[x][1]];
            Rotate(x,nxt^1);Del(s[x][nxt],k);
        }
        else Del(s[x][k>val[x]],k);
        Pushup(x);
    }
}
using namespace Treap;
int n,x,y,cur,cnt,res;
 
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        if(!cnt||cur==x)
            cnt++,cur=x,Insert(rt,y);
        else
        {
            int pre=Pre(rt,y),nxt=Nxt(rt,y),tmp;
            if(nxt-y<y-pre) tmp=nxt-y,Del(rt,nxt);
            else tmp=y-pre,Del(rt,pre);
            cnt--;(res+=tmp)%=MOD;
        }
    }
    printf("%d",res);
    return 0;
}
原文地址:https://www.cnblogs.com/newera/p/9637536.html