• 「题解」洛谷 P2234 [HNOI2002]营业额统计


    题目

    P2234 [HNOI2002]营业额统计

    简化题意

    给你一个长为 (n) 的序列,让你求 (sumlimits_{i = 1} ^ {n} min (abs(a_j - a_i)),j in [1, i - 1))

    思路

    Splay。

    对于一颗建好的 Splay 每次插入 (a_i),最小的贡献只有可能出现在前驱和后继中。

    Code

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream>
    #include <algorithm>
    #define MAXN 33333
    
    int min(int a, int b) { return a < b ? a : b; }
    
    inline void read(int &T) {
        int x = 0;
        bool f = 0;
        char c = getchar();
        while (c < '0' || c > '9') {
            if (c == '-') f = !f;
            c = getchar();
        }
        while (c >= '0' && c <= '9') {
            x = x * 10 + c - '0';
            c = getchar();
        }
        T = f ? -x : x;
    }
    
    int n, ans, root, fa[MAXN], son[MAXN][2];
    int num, size[MAXN], val[MAXN], cnt[MAXN];
    
    namespace Splay {
        int which(int x) { return son[fa[x]][1] == x ? 1 : 0; }
        void update(int x) { size[x] = cnt[x] + size[son[x][0]] + size[son[x][1]]; }
        void clear(int x) { fa[x] = son[x][0] = son[x][1] = cnt[x] = size[x] = val[x] = 0; }
        void rotate(int x) {
            int father = fa[x], grandpa = fa[father];
            int flag1 = which(x), flag2 = which(father);
            fa[x] = grandpa, fa[father] = x;
            if (grandpa) son[grandpa][flag2] = x;
            fa[son[x][flag1 ^1]] = father;
            son[father][flag1] = son[x][flag1 ^1];
            son[x][flag1 ^ 1] = father;
            update(x), update(father);
        }
        void splay(int x) {
            for (int f = fa[x]; f = fa[x], f; rotate(x)) {
                if (fa[f]) rotate(which(x) == which(f) ? f : x);
            }
            root = x;
        }
        int pre() {
            int now = son[root][0];
            while (son[now][1]) now = son[now][1];
            return now;
        }
        int nxt() {
            int now = son[root][1];
            while (son[now][0]) now = son[now][0];
            return now;
        }
        void ins(int x) {
            if (!root) {
                val[++num] = x;
                ++cnt[num];
                root = num;
                update(num);
                return;
            }
            int now = root, f = 0;
            while (1) {
                if (val[now] == x) {
                    ++cnt[now];
                    update(now), update(f);
                    splay(now);
                    return;
                }
                f = now, now = son[now][val[now] < x];
                if (!now) {
                    val[++num] = x;
                    ++cnt[num];
                    fa[num] = f;
                    son[f][val[f] < x] = num;
                    update(num), update(f);
                    splay(num);
                    return;
                }
            }
        }
    }
    
    int main() {
        read(n);
        for (int i = 1, x; i <= n; ++i) {
            read(x);
            Splay::ins(x);
            if (i == 1) ans += x;
            else if (cnt[root] > 1) continue;
            else {
                int minn = 2147483647, maxx = 2147483647;
                if (son[root][0]) minn = val[Splay::pre()];
                if (son[root][1]) maxx = val[Splay::nxt()];
                ans += min(abs(minn - x), abs(maxx - x));
            }
        }
        std::cout << ans << '
    ';
        return 0;
    }
    
  • 相关阅读:
    3.2 playbook tags
    3.1 playbook语法实践
    3. playbook基础组件
    elasticsearch IK中文分词
    elasticsearch参数详解
    2. ansible常用模块
    1. ansible简介
    Python sphinx-build在Windows系统中生成Html文档
    Oracle PL/SQL Developer集成TFS进行团队脚本文件版本管理
    Gulp自动构建Web前端程序
  • 原文地址:https://www.cnblogs.com/poi-bolg-poi/p/13635485.html
Copyright © 2020-2023  润新知