什么是前缀和
原数组: a[1], a[2], a[3], a[4], a[5], …, a[n]
前缀和 Si为数组的前 i项和
前缀和: S[i] = a[1] + a[2] + a[3] + … + a[i]
注意: 前缀和的下标一定要从 1开始, 避免进行下标的转换
s[0] = 0
s[1] = a[1]
s[2] = a[1] + a[2]
前缀和的作用
快速求出元素组中某段区间的和
一维数组求解前缀和(Si)
for循环求出 每个S[i] (将 S[0] 定义为 0, 避免下标的转换)
求 [l, r]中的和, 即为 S[r] - S[l-1]
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N],s[N];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
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];
while(m --)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",s[r] - s[l - 1]);
}
return 0;
}
二维前缀和
S[i,j]
即为图1红框中所有数的的和为:
S[i,j]=S[i,j−1]+S[i−1,j]−S[i−1,j−1]+a[i,j]
(x1,y1),(x2,y2)
这一子矩阵中的所有数之和为:S[x2,y2]−S[x1−1,y2]−S[x2,y1−1]+S[x1−1,y1−1]
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N],s[N];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
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];
while(m --)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",s[r] - s[l - 1]);
}
return 0;
}
来源:AcWing