Solution Of P11702 [ROIR 2025] 不平衡划分

· · 题解

Solution

感觉挺牛的题。

先放结论,事实上一共只有三种情况:

然后答案就是这三种情况的 \max

我们简单解释一下,这样考虑:假设一开始所有数分成若干一段,然后经过若干次变换之后只剩 k 段的过程。

然后答案应该就是这整个过程中只有 k 段所有状态的最大值。

然而你会发现这几个状态一定会被上面的三种情况所覆盖。

因此就可以直接这么做。

Code

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

constexpr int N = 3e5 + 7;
int n, k, a[N], pre[N], suf[N];
i64 sum[N], res;

int main() {
    cin.tie(nullptr) -> sync_with_stdio(false);
    cin >> n >> k;

    fill (pre, pre + n + 2, (int)2e9);
    fill (suf, suf + n + 2, (int)2e9);

    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        sum[i] = sum[i - 1] + a[i];
    }

    for (int i = 1; i <= n; i ++) {
        pre[i] = min (pre[i - 1], a[i]);
    }

    for (int i = n; i >= 1; i --) {
        suf[i] = min (suf[i + 1], a[i]);
    }

    int l = n - k + 1;

    // case 1
    for (int i = l; i <= n; i ++) {
        i64 ans = sum[i] - sum[i - l];
        res = max(ans - min(pre[i - l], suf[i + 1]), res);
    }

    // case 2
    for (int i = 1; i < n; i ++) {
        int x = 2 + (i < n - 1);
        int y = (n - i + 1);
        if (k >= x && k <= y) {
            res = max(res, sum[i] - a[i + 1]);
        }
    }

    // case 3
    for (int i = n - 1; i; i --) {
        int x = 2 + (i > 1);
        int y = i + 1;
        if (k >= x && k <= y) {
            res = max(res, sum[n] - sum[i] - a[i]);
        }
    }

    cout << res << endl;
    return 0;
}