前缀和
前缀和
概念
前缀和算法是一种用于计算数组某个区间所有数字之和的算法
一维数组的前缀和
主要思想:将数组的第0个位置的数字置为0,从数组下标为1的位置开始输入数据,并同时计算前n个数字的总和。
注意:数组的第0个位置被置为0,对计算结果不造成影响,因此接下来的描述不包括数组的第0个位置,只包括数组下标从1开始的数据。
s[i]:前i个数字的和
a[i]:数组里第i个数字
s[i]公式:s[i]=s[i-1]+a[i]
推导过程:
L:数组第L个数字
R:数组第R个数字
R的位置是在L后面的
指定区间L到R的所有数字总和公式=s[R]-s[L-1]
推导过程:
#include<stdio.h>
const int N=100001;
int a[N];
int s[N];
int main()
{
int n,m,l,r;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);//(1)
s[i]=s[i-1]+a[i];//(2)
}
while(m--)
{
scanf("%d %d",&l,&r);
printf("%d\n",s[r]-s[l-1]);//(3)
}
}
(1)将数据输入进数组
(2)利用公式求前n个数字的总和
(3)利用公式计算指定区间的数字总和
二维数组的前缀和
注意:二维数组的前缀和有一个误区,和一维数组的前缀和不同
如图:
左边原数组,右边其前缀和数组
其中b[2][2]的数字为5,其并不像一维数组的前缀和一样
b[2][2]=a[1][1]+a[1][2]+a[1][3]+a[2][1]+a[2][2]
这个对于二维数组的前缀和是错误的
二维数组的前缀和是一个由x,y决定的空间,如b[2][2]应该是a数组这些空间的前缀和:如图:
主要思想:从数组第1行第1列的位置开始存储数据,第0行和第0列的位置都置为0,不进行使用。
注意:接下来的描述不包括第0行和第0列
a[i][j]:数组里第i行第j列的数字
s[i][j]:前i行,j列的所有数字之和
s[i][j]公式:s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]
推导过程:
指定区间a[x1][y1]-a[x2][y2]的数字总和
公式:指定区间和=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]
推导过程:
#include<stdio.h>
const int N=1001;
int a[N][N];
int s[N][N];
int main(){
int n,m,q;
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);//(1)
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];//(2)
}
}
while(q--){
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]);//(3)
}
return 0;
}
(1)将数据输入进n行m列的数组
(2)利用公式求i行,j列的数字总和
(3)利用公式计算指定区间的数字总和