1. 程式人生 > 其它 >bzoj 1588 [HNOI2002]營業額統計

bzoj 1588 [HNOI2002]營業額統計

一句話題意:
每次插入一個數,求序列中與上一個插入數的差的最小值

顯然一個set可以維護這個東西,對於重複元素,我們可以用set多判一判,像我這種比較懶的就在開一個map記錄每個元素有沒有出現過

#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>

using namespace std;

const int INF = 1e8;

int n;
set<int> s;
map<int, int> mp;

int main()
{
    scanf("%d", &n);

    long long res = 0;
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        scanf("%d", &x);
        if (i == 1) res += x;
        else if (!mp.count(x)) // 沒有等於x的數
        {
            int cur = INF;
            auto it = s.upper_bound(x);
            if (it != s.end()) cur = min(cur, abs(x - *it));
            if (it != s.begin())
            {
                it -- ;
                cur = min(cur, abs(x - *it));
            }
            res += cur;
        }
        s.insert(x);
        mp[x] = true;
    }

    printf("%lld\n", res);

    return 0;
}

正經寫個平衡樹吧
寫了個treap(

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long LL;

const int N = 40010, INF = 1e8;

int n;

struct Node
{
    int l, r;
    int key, val;
}tr[N];

int root, idx;

int new_node(int key)
{
    tr[ ++ idx].key = key;
    tr[idx].val = rand();
    return idx;
}

void zig(int &x)
{
    int y = tr[x].l;
    tr[x].l = tr[y].r, tr[y].r = x, x = y;
}

void zag(int &x)
{
    int y = tr[x].r;
    tr[x].r = tr[y].l, tr[y].l = x, x = y;
}

void build()
{
    new_node(-INF), new_node(INF);
    root = 1, tr[1].r = 2;

    if (tr[1].val < tr[2].val) zag(root);
}

void insert(int &p, int key)
{
    if (!p) p = new_node(key);
    else if (tr[p].key == key) return;
    else if (tr[p].key > key)
    {
        insert(tr[p].l, key);
        if (tr[p].val < tr[tr[p].l].val) zig(p); 
    }
    else
    {
        insert(tr[p].r, key);
        if (tr[p].val < tr[tr[p].r].val) zag(p);
    }
}

int get_prev(int p, int key)
{
    if (!p) return -INF;
    if (tr[p].key > key) return get_prev(tr[p].l, key);
    return max(tr[p].key, get_prev(tr[p].r, key));
}

int get_next(int p, int key)
{
    if (!p) return INF;
    if (tr[p].key < key) return get_next(tr[p].r, key);
    return min(tr[p].key, get_next(tr[p].l, key));
}

int main()
{
    build();

    cin >> n;

    LL res = 0;
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        cin >> x;
        if (i == 1) res += x;
        else res += min(x - get_prev(root, x), get_next(root, x) - x);
        insert(root, x);
    }

    cout << res << endl;

    return 0;
}