HNOI2002营业额统计

Posted ssttkkl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HNOI2002营业额统计相关的知识,希望对你有一定的参考价值。

https://www.luogu.org/problem/show?pid=2234

用Treap维护,每次查询这个数的前驱与后继哪个和它差值更小。

由于查询一个数时在Treap走出的路径必定经过它的前驱与后继,故直接在走的过程统计答案就可以了。

#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
namespace treap
{
enum direction
{
    l = 0,
    r = 1
};
struct node
{
    int val, prio;
    node *ch[2];
    node(int v) : val(v), prio(rand()) { ch[l] = ch[r] = NULL; }
    int cmp(int v) { return (v < val) ? l : r; }
} * root;
void rotate(node *&t, int d)
{
    node *k = t->ch[d ^ 1];
    t->ch[d ^ 1] = k->ch[d];
    k->ch[d] = t;
    t = k;
}
void insert(int v, node *&t = root)
{
    if (t == NULL)
        t = new node(v);
    else if (v == t->val)
        return;
    else
    {
        int d = t->cmp(v);
        insert(v, t->ch[d]);
        if (t->prio > t->ch[d]->prio)
            rotate(t, d ^ 1);
    }
}
int closest(int v, node *t = root) //返回与v的差的绝对值最小的差值
{
    int ans = t == NULL ? v : abs(t->val - v);
    while (t != NULL)
    {
        ans = min(ans, abs(t->val - v));
        t = t->ch[t->cmp(v)];
    }
    return ans;
}
}
int main()
{
    using namespace treap;
    srand(20001209);
    int n, tot = 0, a;
    cin >> n;
    while (n--)
    {
        cin >> a;
        tot += closest(a);
        insert(a);
    }
    cout << tot << endl;
    return 0;
}

 

以上是关于HNOI2002营业额统计的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1588: [HNOI2002]营业额统计

链表BZOJ1588: [HNOI2002]营业额统计

bzoj1588: [HNOI2002]营业额统计

bzoj1588:[HNOI2002]营业额统计

BZOJ 1588 [HNOI2002]营业额统计

[HNOI2002]营业额统计