zoukankan      html  css  js  c++  java
  • 【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
    ",ans);
    
        return 0;
    }
  • 相关阅读:
    并发编程之线程进阶
    并发编程之线程
    进程间通信(队列和管道)
    在python程序中的进程操作
    操作系统之进程
    网络编程之黏包
    树莓派 websocket 控制LED
    lua 调用 C -- 实例 C函数作为应用程序的一部分
    linux 环境下进程什么时候会被 killed掉
    STM32 + cJSON 死机问题解决
  • 原文地址:https://www.cnblogs.com/evenbao/p/9315329.html
Copyright © 2011-2022 走看看