loj10144. 「一本通 4.6 练习 1」宠物收养所

Posted junk-yao-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了loj10144. 「一本通 4.6 练习 1」宠物收养所相关的知识,希望对你有一定的参考价值。

思路:

  treap+简单模拟。

  我只能说:注意取模!!!!

 

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn = 80010;
inline void qread(int &x) {
    x = 0;
    register int ch = getchar(), flag = 0;
    while(ch < 0 || ch > 9)        {
        if(ch == -)    flag = 1;
        ch = getchar();
    }
    while(ch >= 0 && ch <= 9)    x = 10 * x + ch - 48, ch = getchar();
    if(flag)    x = -x;
}
int rt = 0, tpn, v[maxn], l[maxn], r[maxn], R[maxn], sz[maxn], vn[maxn];
inline void update(int x) {
    sz[x] = sz[l[x]] + sz[r[x]] + vn[x];
}
inline void zig(int &x) {
    int t = l[x];
    l[x] = r[t];
    r[t] = x;
    update(x);
    update(t);
    x = t;
}
inline void zag(int &x) {
    int t = r[x];
    r[x] = l[t];
    l[t] = x;
    update(x);
    update(t);
    x = t;
}
void insert(int &x, int w) {
    if(!x)    {
        x = ++tpn;
        v[x] = w;
        R[x] = rand();
        sz[x] = vn[x] = 1;
        return ;
    }
    if(w < v[x])    insert(l[x], w);
    else if(w > v[x])    insert(r[x], w);
    else            vn[x]++;
    update(x);
    if(l[x] && R[l[x]] < R[x])    zig(x);
    if(r[x] && R[r[x]] < R[x])    zag(x);
}
void pop(int &x, int w) {
    if(w < v[x])    pop(l[x], w);
    else if(w > v[x])    pop(r[x], w);
    else {
        if(vn[x] > 1)    vn[x]--;
        else if(!l[x] || !r[x])    x = l[x] | r[x];
        else if(R[l[x]] < R[r[x]])    zig(x), pop(x, w);
        else                        zag(x), pop(x, w);
    }
    update(x);
}
int ask(int x, int w){
    if(!x)        return -1;
    if(w < v[x])    return ask(l[x], w);
    if(w > v[x])    return ask(r[x], w);
    return     x;
}
int findk(int x, int k){
    if(k >= sz[l[x]] + 1 && k <= sz[l[x]] + vn[x])    return v[x];
    if(k <= sz[l[x]])    return findk(l[x], k);
    return     findk(r[x], k - sz[x] - vn[x]);
}
int findpre(int x, int w){
    int res = -0x3f3f3f3f;
    while(x){
        if(w <= v[x])    x = l[x];
        else            res = v[x], x = r[x];
    }
    return res;
}
int findnxt(int x, int w){
    int res = 0x3f3f3f3f;
    while(x){
        if(w < v[x])    res = v[x], x = l[x];
        else            x = r[x];
    }
    return res;
}
int main(void) {
    srand(11535);
    int n, ans = 0, mode = 0;
    qread(n);
    for(int i=1; i<=n; ++i){
        int x, a;
        qread(x), qread(a);
        if(!sz[rt]) {
            insert(rt, a);
            mode = x;
            continue;
        }
        if(x != mode){
            if(ask(rt, a) == -1){
                int l = findpre(rt, a), r = findnxt(rt, a);
                int minn = min(a - l, r - a), d;
                if(a + minn == r)    d = r;
                if(a - minn == l)    d = l;
                pop(rt, d);
                ans += minn;
                ans %= 1000000;
            }
            else pop(rt, a);
        }
        else
            insert(rt, a);
    }    
    printf("%d
", ans%1000000);
}

 

以上是关于loj10144. 「一本通 4.6 练习 1」宠物收养所的主要内容,如果未能解决你的问题,请参考以下文章

loj10143. 「一本通 4.6 例 1」营业额统计

loj10195. 「一本通 6.1 练习 2」转圈游戏 (loj2608)

loj10188. 「一本通 5.6 练习 1」玩具装箱

loj10150. 「一本通 5.1 练习 1」括号配对

loj10139. 「一本通 4.5 练习 1」树上操作(loj2125. 「HAOI2015」树上操作 )

loj10194. 「一本通 6.1 练习 1」A 的 B 次方