个人主页:Weraphael
✍作者简介:目前正在学习c++和算法
✈️专栏:【C/C++】算法
希望大家多多支持,咱一起进步!
如果文章有啥瑕疵
希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论 点赞 收藏 加关注
前缀和就是新建一个数组,数组中保存的是原数组前
n
项的和
【举个例子】
我们可以利用上面的图来找找规律
【代码】
for (int i = 1;i <= n;i++)
{
s[i] = s[i-1] + a[i];
}
能快速求出数列中某一段的和,时间复杂度为O(1)
还是要利用这幅图
假设我们要计算原数组a中区间[2,4]的和,我们就可以用S4 - S1,
l,r]
的和,其实也能循环遍历,不过时间复杂度是O(N),而前缀和的时间复杂度是O(1)#include
using namespace std;
const int N = 100010;
int a[N],s[n];
int main()
{
int n; //n - 原数组元素的个数
scanf("%d",&n);
//输入原数组
for (int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
}
//前缀和公式
for (int i = 1;i <= n;i++)
{
s[i] = s[i - 1] + a[i];
}
//以下是计算某段区间的和
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",s[r] - s[l - 1]);
return 0;
}
- 首先,下标从1开始就是为了定义S0,就拿前缀和公式来说,
S[i] = S[i-1] + a[i]
,当i = 1
时,出现了S0,而S0要及时置为0,原因是为了统一。举个例子,假设要计算区间[1,10]
之间的和,明眼就能看出是要计算S10,而为了达到统一计算的效果,S10 - S0 = S10 - 0.- 为什么我在代码中没有定义
S[0]=0
,原因是我将s[N]
定成了全局变量,而全局变量有一个特点:默认初始化为0!
目的是求出一个矩阵中某一个小矩阵的和
大家画图可能会更加容易理解点,假设点(i,j)在矩阵的正中心,S[i][j]
即为黄色部分所有数的的和
我们可以分三步求出黄色部分的和
列出式子:
S[i][j] = S[i][j-1] + ...
列出式子:
S[i][j] = S[i][j-1] + S[i-1][j] + ...
最后别忘了加上了本身:
a[i][j]
列出式子:S[i][j] = S[i][j-1] + S[i-1][j] - S[i-1][j-1] + a[i][j]
假设要求左上角为(x1,y1),右下角为(x2,y2)所围成黄色部分所有数的和
子矩阵的求法和求S[i][j]
是类似的,四步走
列出式子:
S = S[x2][y2] - ...
列出式子:
S = S[x2][y2] - S[x1 - 1][y2] - ...
列出式子:
S = S[x2][y2] - S[x1 - 1][y2] - S[x2][y1 - 1] + ...
列出式子:
S = S[x2][y2] - S[x1 - 1][y2] - S[x2][y1 - 1] + S[x1 - 1][y1 - 1]
#include
using namespace std;
const int N = 10010;
int n, m;
int a[N][N],s[N][N];
int main()
{
scanf("%d%d%d", &n, &m); //n -行 m - 列
//输入数组
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
scanf("%d", &a[i][j]);
//二维前缀和公式
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
//求子矩阵
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
return 0;
}
其实大家只要背下前缀和公式就好了
S[i]= S[i-1] + a[i]
[l,r]
: S[r]- S[l-1]
S[i][j] = S[i][j-1] + S[i-1][j] - S[i-1][j-1] + a[i][j]
S = S[x2][y2] - S[x1 - 1][y2] - S[x2][y1 - 1] + S[x1 - 1][y1 - 1]