一维差分专题
前缀和与差分的核心在于预处理,能在暴力枚举中快速给出查询结果,从而优化时间复杂度。本质上,它们是一对互逆运算。
差分原理
构建方式
根据定义,差分数组 f 与原数组 a 的关系为:
f[i] = a[i] - a[i-1]
利用差分数组的性质,也可以理解为对区间 [i, i] 加上 a[i],即 f[i] += a[i], f[i+1] -= a[i]。
区间修改
处理区间 [L, R] 增加 c 时,核心公式为:
f[L] += c;
f[R + 1] -= c;
这保证了只有 L 到 R 之间的元素在还原后受到影响。
还原数组
对差分数组做一次「前缀和」,即可还原出原数组:
for(int i = 1; i <= n; i++) f[i] += f[i - 1];
经典算法题实战
3.1【模板】差分
题目描述
给定一个长度为 n 的数组,进行 m 次操作,每次将区间 [l, r] 内的数都加上 k,最后输出整个数组。
思路解析
直接模拟区间修改的时间复杂度是 O(n*m),数据量大时会超时。使用差分数组可以将单次修改降为 O(1),最后统一还原,总复杂度 O(n+m)。
这里提供两种实现方式:一种是基于差分数组性质的初始化,另一种是基于定义的显式计算。
代码实现
方法一:根据差分数组的性质
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int f[N];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
x;
cin >> x;
f[i] += x;
f[i + ] -= x;
}
(m--) {
l, r, k;
cin >> l >> r >> k;
f[l] += k;
f[r + ] -= k;
}
( i = ; i <= n; i++) {
f[i] += f[i - ];
cout << f[i] << ;
}
;
}


