すべての更新 (加算/減算) 操作は、最大値/最小値を見つける前に行われると想定します。更新操作と最小/最大操作を混在させるための適切なソリューションがありません。
配列のインデックス i の値が元の配列のインデックス i とインデックス (i - 1) の差であるプレーンな配列を使用できます。これにより、配列のインデックス 0 からインデックス i までの合計が、元の配列のインデックス i の値になります。
減算は、負の数との加算なので、同じように扱うことができます。元の配列のインデックス i からインデックス j まで k を追加する必要がある場合、配列のインデックス i に k を追加し、配列のインデックス (j + 1) から k を減算します。これには、更新ごとに O(1) 時間がかかります。
値を合計して累積し、最大値/最小値を記録することで、元の配列の最小値/最大値を見つけることができます。これには、操作ごとに O(n) 時間がかかります。これは、配列全体に対して 1 回行われると想定しています。
擬似コード:
a[N] // Original array
d[N] // Difference array
// Initialization
d[0] = a[0]
for (i = 1 to N-1)
d[i] = a[i] - a[i - 1]
// Addition (subtraction is similar)
add(from_idx, to_idx, amount) {
d[from_idx] += amount
d[to_idx + 1] -= amount
}
// Find max/min for the WHOLE array after add/subtract
current = max = min = d[0];
for (i = 1 to N - 1) {
current += d[i]; // Sum from d[0] to d[i] is a[i]
max = MAX(max, current);
min = MIN(min, current);
}