voidmyinsert(int l, int r, int val) { vals[l] += val, vals[r + 1] -= val; }
intmain() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { int val; scanf("%d", &val); myinsert(i, i, val); } while (m--) { int l, r, c; scanf("%d%d%d", &l, &r, &c); myinsert(l, r, c); } int res = 0; for (int i = 1; i <= n; i++) { res += vals[i]; printf("%d ", res); } return0; }
一开始输入的数组被看作一个前缀和数组。一开始使用 $myinsert(i, i, val)$ 构造出了一个新数组,这个新数组的前缀和是原数组。直接对原数组一个区间上的一次修改操作是 $O(n)$ 的,现在对新数组修改一次是 $O(1)$ 的;最终结果则是新数组求一次前缀和就能得到答案结果数组。