Official
N - 連続部分列の和の最大値 / Maximum Subarray Sum Editorial
by
N - 連続部分列の和の最大値 / Maximum Subarray Sum Editorial
by
sounansya
長さ \(K\) の連続部分列 \(N-K+1\) 個それぞれの操作を遅延セグメント木で管理することを考えます。
各クエリでは \(A_i\) の値を \(x\) に変更しますが、これは \(A_i\) の値を \(x-A_i\) 増やすというように捉えることができます。この値の変更は 0-indexed で \(\max(0,i-K+1)\) 番目から \(\min(N-K,i)\) 番目までの連続部分列の総和がそれぞれ \(x-A_i\) だけ増えることになります。
各変更クエリ後の答えは全ての連続部分列の総和の最大値なので、区間加算・区間 max の遅延セグメント木を用いることでこの問題を \(O(N+Q\log N)\) 時間で解くことができます。
実装例(C++) (\(O(N+(N+Q)\log N)\) 解)
#include <atcoder/lazysegtree>
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
constexpr long INF = 4e18;
long op(long a, long b) { return max(a, b); }
long e() { return 0; }
long mapping(long f, long x) { return f + x; }
long composition(long f, long g) { return f + g; }
long id() { return 0; }
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n, k;
cin >> n >> k;
vector<long> a(n);
rep(i, n) cin >> a[i];
atcoder::lazy_segtree<long, op, e, long, mapping, composition, id> seg(n - k + 1);
rep(i, n) seg.apply(max(0, i - k + 1), min(n - k + 1, i + 1), a[i]);
int q;
cin >> q;
while (q--) {
int i;
long x;
cin >> i >> x;
i--;
seg.apply(max(0, i - k + 1), min(n - k + 1, i + 1), x - a[i]);
a[i] = x;
cout << seg.all_prod() << '\n';
}
}
posted:
last update:
