牛客 226303 【模板】差分
牛客226303 【模板】差分
思路🧐:
本篇将对差分算法进行基本认识,差分算法是一种通过处理数据间的差异(差分)来优化计算或解决问题的策略,核心思想是通过操作差分值来间接处理原始数据,从而简化计算或提升效率。
构建差分数组
diff
,其中diff[i] = a[i] - a[i-1]
。对区间[L, R]
增加k
时,只需修改两个端点:diff[L] += k
,diff[R+1] -= k
(若存在)。通过前缀和操作还原更新后的原数组,此时由于从L开始增加了k,还原后依然增加k,R+1之后减去k,则之后的元素将会还原,时间复杂度降为O(1)
单次操作。例如:
初始数组:
v = [3, 5, 7, 2]
,差分数组diff = [3, 2, 2, -5]
。
操作:对区间[2, 3]
(即5, 7
)加4
。步骤 1:修改差分数组
diff[2] += 4
→diff = [3, 6, 2, -5]
。diff[4] -= 4
→diff = [3, 6, 2, -9]
。步骤 2:还原原数组
v[1] = 0 + 3 = 3
,v[2] = 3 + 6 = 9
(5->9
,增加了4
),v[3] = 9 + 2 = 11
(7->11
,增加了4
),v[4] = 11 + (-9) = 2
(2
保持不变,因为增量被diff[4] -= 4
抵消)。结果:
v = [3, 9, 11, 2]
,仅[2, 3]
被修改。
代码🔎:
#include <iostream> #include <vector> using namespace std; int main() { int n, m; cin >> n >> m; vector<long long> v(n + 1); for (int i = 1; i <= n; i++) { cin >> v[i]; } vector<long long> diff(n + 1); for (int i = 1; i <= n; i++) { diff[i] = v[i] - v[i - 1]; // 差分计算 } while (m--) { int l, r, k; cin >> l >> r >> k; diff[l] += k; if (r + 1 <= n) diff[r + 1] -= k; // 区域内加了,区域外就需要减回去 } // 前缀和还原 for (int i = 1; i <= n; i++) { v[i] = v[i - 1] + diff[i]; } for (int i = 1; i <= n; i++) { cout << v[i] << " "; } return 0; }