前缀和与差分

前缀和与差分

先记一下前缀和,比较简单。

前缀和

一维前缀和

一维前缀和:能以(O(1))的时间完成求一段区间上的和。

定义:s[i] = a[1] + a[2] + ... + a[i]

求解(l-r)上的和就是s[r]-s[l-1]

二维前缀和

就是把一维的拓展了一下,相对应的求解s[i]的方式会稍微更复杂一点

定义:S[i][j] = 第i行j列格子左上部分所有元素的和

接下来的画个图很好理解,求一块子矩阵(x1y1x2y2)的方式就是:

Sum = S[x2][y2] - S[x1 - 1][y2] - S[x2][y1 - 1] + S[x1 - 1][y1 - 1]

差分

差分是前缀和的逆运算,相对难理解一点。

原数组a[n]就是差分数组s[n]的前缀和数组

差分的作用:能以(O(1))的时间来完成区间上的加法。

其实要求差分数组比较难,最简单的理解方式:

先想象原数组a[n]全是0,每次向里加一个数字,就是对这一块的区间进行了一次加法。

所以差分只有一个功能,就是向一段区间同时增改一个数字。建立差分数组也用这个思想。

一维差分

自己推一下就知道,在差分数组里,向s[i]加一个数val,会影响向后所有的数据,所以在s[r+1]里补回来即可。

[l,r]进行一次加法: s[l] += val,s[r+1] -= val

二维差分

和一维差分同样的思想,只不过更难推一点。

x1y1x2y2同时加一个数的方法是:

void insert(int x1, int y1, int x2, int y2, int val)
{
    s[x1][y1] += val;
    s[x2 + 1][y1] -= val;
    s[x1][y2 + 1] -= val;
    s[x2 + 1][y2 + 1] += val;
}
原文地址:https://www.cnblogs.com/Salty-Fish/p/13526149.html