[HAOI2008]糖果传递
Description
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
最小化绝对值的和可以想中位数。