[HAOI2008]糖果传递

Description

BZOJ1045

Luogu2512

Solution

\(s_i\)表示\(i\)\(i-1\)的糖果数(可以为负),答案就是\(\sum |s_i|\),对于每个人都有式子\(s_{i+1}-s_i+a_i=ave\),然后把\(s_i\)\(s_1\)表示为\(s_1-sum_{i-1}+(i-1)ave\),就转化成了中位数。

Code

const int N = 1000010;

ll a[N], s[N], S[N], ave, n;
ll abs(ll x) { return x > 0 ? x : -x; }

void main() {
    n = read();
    for (int i = 1; i <= n; ++i) a[i] = read(), s[i] = s[i - 1] + a[i];
    ave = s[n] / n;
    for (int i = 1; i <= n; ++i) {
        S[i] = (i - 1) * ave - s[i - 1];
    }
    std::sort(S + 1, S + n + 1);
    ll ans = 0, tmp = (n % 2) ? S[n / 2 + 1] : (S[n / 2] + S[n / 2 + 1]) / 2;
    tmp *= -1;
    for (int i = 1; i <= n; ++i) {
        ans += abs(tmp - s[i - 1] + (i - 1) * ave);
    }
    printf("%lld\n", ans);
}

Note

最小化绝对值的和可以想中位数。

posted @ 2018-10-28 19:47  wyxwyx  阅读(108)  评论(0编辑  收藏  举报