差分和前缀和的关系就类似于导数和积分的关系,差分是前缀和的逆运算简单的说就是这样。
假如说我们有一个长度为n的数组,而我们想要在其中l到r之间增加一个常数c,我们就可以用差分,如果我们运用暴力运算时间复杂度是O(n)但是我们用差分的话能把时间复杂度降低到O(1),我们先来简单讲一下差分
我们先定义两个数组一个作前缀和,另一个做前一个数组的差分
int a[N],b[N];
其中a[n]=b[1]+b[2]+b[3]+....+b[n]和高中的等差数列求和一样,因此我们要让其中[l,r]的区间增加一个常数c,我们只需要让b[l]+=c,这样l之后的数组a都会增加一个常数c,但是这不是我们想要的结果,我们只想让其中一段增加c就行,因此在区间的右边界往后的一个数减去一个c就把前面增加的一个c抵消了,代码如下。
void add(int l,int r,int c)
{
b[l]+=c;
b[r+1]-=c;
}
设我们输入了一堆数在数组a中,但是我们要如何把这个数组转换成差分数组呢?
for(int i=1;i<=n,i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) insert(i,i,a[i]);//初始化差分数组b
这边我们让i=1而不是0方便后面的操作。
然后我们再用上面定义的insert函数对数组b进行操作使其区间的左右端进行操作
最后我们再用求前缀和的方法将该数组转化为前缀和数组
for(int i=1;i<=n;i++) b[i]+=b[i-1];//这边需要提前把b[0]=0
所以就类似于导数和积分的关系,我对导数进行积分就求到了导数的原函数,而这里等差数组就相当于前缀和数组的“原函数”。