显然,为了让 max(b[n], c[1]) 最小,当 a[i] > a[i - 1]时,b[i] = b[i - 1] + a[i] - a[i - 1], c[i] = c[i - 1]。当a[i] < a[i - 1]时,b[i] = b[i - 1], c[i] = c[i - 1] + a[i] - a[i - 1]
假设K = Σ max(0, a[i] - a[i - 1]),则a[1] - c[1] + K = b[n], 为了最小化b[n]和c[1],显然c[1] = (a[1] + K) / 2, 每次区间改变都可以用O(1)复杂度维护
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; long long a[N], d[N]; int main() { int n; scanf("%d", &n); long long k = 0; for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); d[i] = a[i] - a[i - 1]; if (i != 1) k = k + max(0ll, d[i]); } printf("%lld ", max(a[1] + k - (a[1] + k) / 2, (a[1] + k) / 2)); int q; scanf("%d", &q); while (q--) { long long l, r, x; scanf("%lld %lld %lld", &l, &r, &x); if (l == 1) a[1] += x; else { long long t = d[l] + x; k += max(t, 0ll) - max(d[l], 0ll); d[l] += x; } if (r != n) { long long t = d[r + 1] - x; k += max(t, 0ll) - max(d[r + 1], 0ll); d[r + 1] -= x; } long long X = (a[1] + k) / 2; printf("%lld ", max(X, a[1] + k - X)); } return 0; }