【HNOI 2004】宠物收养所

【题目链接】

           https://www.lydsy.com/JudgeOnline/problem.php?id=1208

【算法】

            建两棵平衡树维护领养者和宠物的特点值,这两棵平衡树支持 插入删除,查询前驱和后继

            笔者的平衡树选用的是Treap,当然,Splay,Set等数据结构也是可以完成这个任务的

【代码】

            

#include<bits/stdc++.h>
using namespace std;
#define MAXN 80010
typedef long long ll;
const ll INF = 1e15;
const int P = 1000000;

int i,n,ans,a;
ll p,q,b;

struct Treap
{
    int root,total;
    struct Node
    {
        int l,r;
        int priority;
        ll val;    
    } a[MAXN];
    inline void new_node(int pos,ll x)
    {
        a[pos].priority = rand();
        a[pos].val = x;    
    }
    inline void zig(int &p)
    {
        int q = a[p].l;
        a[p].l = a[q].r; a[q].r = p; 
        p = q;    
    }
    inline void zag(int &p)    
    {
        int q = a[p].r;
        a[p].r = a[q].l; a[q].l = p;
        p = q;
    }
    inline void insert(int &x,ll val)
    {
        int now;
        if (!root)
        {
            new_node(++total,val);
            root = total;
            return;
        }
        if (val < a[x].val)
        {
            if (a[x].l) 
            {
                insert(a[x].l,val);
                if (a[a[x].l].priority > a[x].priority) zig(x);    
            } else 
            {    
                new_node(++total,val);
                a[x].l = total;
            }
        } else
        {
            if (a[x].r)
            {
                insert(a[x].r,val);
                if (a[a[x].r].priority > a[x].priority) zag(x);
            } else
            {
                new_node(++total,val);
                a[x].r = total;
            }
        }
    }
    inline void erase(int &x,ll val)
    {
        if (x == 0) return;
        if (a[x].val == val)
        {
            if (a[x].l || a[x].r)
            {
                if (a[x].r == 0 || a[a[x].l].priority > a[a[x].r].priority) 
                {
                    zig(x);
                    erase(a[x].r,val);
                } else
                {
                    zag(x);
                    erase(a[x].l,val);
                }
            } else x = 0;
        } else
        {
            if (val < a[x].val) erase(a[x].l,val);
            else erase(a[x].r,val);
        }
    }
    inline ll pred(int x,ll val)
    {
        ll t;
        if (!x) return -INF;
        if (a[x].val == val) return val;
        if (val > a[x].val) 
        {
            t = pred(a[x].r,val);
            return (t == -INF) ? a[x].val : t; 
        } else return pred(a[x].l,val);
    }
    inline ll succ(int x,ll val)
    {
        ll t;
        if (!x) return INF;
        if (a[x].val == val) return val;
        if (val < a[x].val)
        {
            t = succ(a[x].l,val);
            return (t == INF) ? a[x].val : t;
        } else return succ(a[x].r,val);
    }
} T1,T2;

int main()
{
    
    srand(123456);
    scanf("%d",&n);
    for (i = 1; i <= n; i++)
    {
        scanf("%d%lld",&a,&b);
        if (a == 0) 
        {
            if (T2.root) 
            {
                 p = T2.pred(T2.root,b);
                q = T2.succ(T2.root,b);
                if (p == -INF && q == INF) continue;
                if (b - p <= q - b) 
                {
                    T2.erase(T2.root,p);
                    ans = (ans + b - p) % P;
                }
                else 
                {
                    T2.erase(T2.root,q);
                    ans = (ans + q - b) % P;
                }
            } else T1.insert(T1.root,b);
        } else 
        {
            if (T1.root)
            {
                p = T1.pred(T1.root,b);
                q = T1.succ(T1.root,b);
                if (p == -INF && q == INF) continue;
                if (b - p <= q - b) 
                {
                    T1.erase(T1.root,p);
                    ans = (ans + b - p) % P;
                }
                else 
                {
                    T1.erase(T1.root,q);
                    ans = (ans + q - b) % P;
                }
            } else T2.insert(T2.root,b);
        }
    }
    printf("%d\n",ans);

    return 0;
}

 

posted @ 2018-07-15 22:42  evenbao  阅读(245)  评论(0编辑  收藏  举报