1. 程式人生 > 實用技巧 >[題解][HNOI2002][Luogu P2234] 營業額統計

[題解][HNOI2002][Luogu P2234] 營業額統計

題目描述

[HNOI2002][Luogu P2234] 營業額統計

題目大意

給定 \(n\) 個整數,求每個數和它之前的數的差的絕對值的最小值之和。

題解

暴力是 \(\mathcal{O}(n^2)\) ,本來能卡過的,結果被洛谷改小了時限。
想到對於每個數要快速找到離它最近的數,而平衡樹的前驅後繼正好滿足要求。
可以用vector當平衡樹
(multiset也行)

code

785B, 481ms

#include <algorithm>
#include <vector>
#include <cstdio>

#define MAXINT 0x7fffffff
using namespace std;

int Aabs(int x) {
    return x >= 0 ? x : -x;
}

int main() {
    vector<int> tree;
    tree.push_back(-MAXINT);

    int n, ans = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        int x;
        scanf("%d", &x);
        if (i == 1) {
            ans += x;
        } else {
            int a = *--lower_bound(tree.begin(), tree.end(), x);
            int b = *lower_bound(tree.begin(), tree.end(), x);
            if (a == -MAXINT)
                ans += Aabs(b - x);
            else
                ans += min(Aabs(a - x), Aabs(x - b));
        }

        tree.insert(upper_bound(tree.begin(), tree.end(), x), x);
    }
    printf("%d\n", ans);
    return 0;
}