一维差分
差分:是前缀和的逆运算
差分数组:
有了数组b,就可以在O(n)得到数组a
差分数组的作用
问题:输入一个长度为 n 的整数序列。接下来输入 m 个操作,每个操作包含三个整数 l,r,c,表示将序列中 [l,r] 之间的每个数加上 c。
暴力的解法是遍历区间[l,r],每次再进行m次操作,时间复杂度是O(mn),若给的数据很多,可能就过不掉了。下面用差分数组进行优化,数组a是数组b的前缀和,我们对数组b的b[i]操作就会影响数组a的a[i]及后面的每个数。
- 首先对数组b的b[l] + c,通过前缀和,a数组变成a[l] + c,a[l+1]+c, … a[n]+c
- 再对数组b的b[r+1] -c,通过前缀和, a数组变成a[r+1] -c,a[r+2]-c,… a[n]+c
通过图理解一下:
小妙招:我们不用去构造差分数组,我们可以把原数组看成全是0,那么差分数组也全是0,经过n次操作变成an,例如:a1是在区间[1,1]+a1,a2是在区间[2,2]+a2…an是在区间[n,n] + an,差分就剩一个操作就是b[l] +c,b[r+1]-c.
实战例题
https://www.acwing.com/problem/content/799/
代码如下:
#include<iostream>
using namespace std;
const int N = 100010;
int a[N],b[N];
void insert(int l,int r,int c)
{
b[l] += c;
b[r+1] -= c;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m