BZOJ1208 宠物收养所

来源:互联网 发布:英汉翻译哪个软件最好 编辑:程序博客网 时间:2024/05/17 06:02

题目链接

题目是中文描述,题意也就不赘述了

实际上我们是动态维护两个集合,对于一个集合,当进入一个新的数的时候,在另一个集合的已有的数中找一个和它最接近的,然后把这个两数取出来,计算绝对值。

数据已经保证每一个集合里面的每一个数都是不一样的,那么这道题就简单了,我们只需要维护两棵平衡树,我选择的是喜闻乐见的Treap……

那么某一个集合进入一个新数的时候,我们只需要询问另外一个集合是否为空,假设不为空,我们就询问一下它的前驱以及后继,找到那个最接近的就行……

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cstdlib>using namespace std;const int N = 80010;const int inf = ~0u >> 1;const int mod = 1000000;struct Treap{    struct node{        node *ch[2];        int v, p, sz;        node(int _v, node *n):            v(_v){ch[0] = ch[1] = n; p = rand(); sz = 1;}        void update(){sz = ch[0]->sz + 1 + ch[1]->sz;}    };    node *root, *null;    Treap(){    }    void init(){        null = new node(0, 0); null->sz = 0; null->p = inf;        null->ch[0] = null->ch[1] = null;        root = null;    }    void rotate(node *&t, bool d){        node *_t = t->ch[d];        t->ch[d] = _t->ch[!d];        _t->ch[!d] = t;        _t->update();        t->update();        t = _t;    }    void __insert(node *&t, int val){        if (t == null){            t = new node(val, null);            return;        }        bool d = val > t->v;        __insert(t->ch[d], val);        if (t->ch[d]->p < t->p) rotate(t, d);        t->update();    }    void __del(node *&t, int val){        if (t == null) return;        if (val == t->v){            bool d = t->ch[1]->p < t->ch[0]->p;            if (t->ch[d] == null){                delete t; t = null; return;            }            rotate(t, d);            __del(t->ch[!d], val);        }else{            bool d = val > t->v;            __del(t->ch[d], val);        }        t->update();    }    void __show(node *t){        if (t == null) return;        __show(t->ch[0]);        printf("%d ", t->v);        __show(t->ch[1]);    }    void insert(int val){        __insert(root, val);    }    void del(int val){        __del(root, val);    }    node *pred(node *t, int val, node *ans){        if (t == null) return ans;        if (t->v <= val)            return pred(t->ch[1], val, t);        else            return pred(t->ch[0], val, ans);    }    node *succ(node *t, int val, node *ans){        if (t == null) return ans;        if (t->v >= val)            return succ(t->ch[0], val, t);        else             return succ(t->ch[1], val, ans);    }    void show(){        __show(root);        puts("");    }    void __fre(node *t){        if (t == null) return;        __fre(t->ch[0]);        __fre(t->ch[1]);        delete t;    }    void fre(){        __fre(root);    }    int size(){        return root->sz;    }    int solve(int val){        node *pre, *suc;        pre = pred(root, val, null);        suc = succ(root, val, null);        if (pre != null && suc != null){            if (abs(val - (pre->v)) > abs(val - (suc->v))){                del(suc->v);                return abs(val - (suc->v));            }else{                del(pre->v);                return abs(val - (pre->v));            }        }else if (pre == null){            del(suc->v);            return abs(val - (suc->v));        }else if (suc == null){            del(pre->v);            return abs(val - (pre->v));        }    }};int n, op, a;Treap x, y;int main(){    scanf("%d", &n);    x.init(); y.init();    int ans = 0;    for (int i = 1; i <= n; i++){        scanf("%d%d", &op, &a);        if (op == 0){            if (y.size() == 0)                x.insert(a);            else                ans = (ans + y.solve(a)) % mod;        }else{            if (x.size() == 0)                y.insert(a);            else                ans = (ans + x.solve(a)) % mod;        }    }    printf("%d\n", ans % mod);    return 0;}


原创粉丝点击