前缀和定义
前缀和是一个数组的某项下标之前(包括此项元素)的所有数组元素的和。
原数组:a[1],a[2],a[3],a[4],a[5];
前缀和:s[i]表示原数组前i个元素的和,及s[i]=a[1]+a[2]+a[3]+……+a[i]
注意:前缀和的存储需要从下标1开始,因为需要用到前0个数的和。
前缀和的作用
用于以O(1)的时间复杂度求出数组的区间和。
例如求数组a[1]+a[2]+a[3]的和,即可使用sum=s[3]-s[0]得到,不需要逐个遍历。
一维数组求解前缀和
例题:已知区间,求出区间和。
代码:
void init(int a[],int s[],int n)//初始化函数,求出前缀和数组
{ //需要参数原数组a,前缀和数组s,长度n
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+a[i];
}
}
int sum(int s[],int l,int r)// 求和函数,使用求和函数前需要调用初始化函数,
{ //需要参数提供参数,前缀和数组以及范围。
return s[r]-s[l-1];
}
二维数组求解前缀和
二位数组求子矩阵的和,s[i][j]表示:左上角坐标为(1,1)(第一行和第一列不存值),右下角坐标为(i,j)矩阵的和。
原数组为a[][],前缀和数组为s[][].
求前缀和:s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
例如求s[5][5]=s[4][5]+s[5][4]-s[4][4]+a[5][5].
求子矩阵的和:左上角为(x1,y1),右下角为(x2,y2)
Sum=s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
求如图蓝色区域的和:sum=s[4][5]-s[4][1]-s[1][5]+s[1][1];
代码
void init(int a[][N],int s[][N],int n,int m)
{
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 sum(int s[][N],int x1,int y1,int x2,int y2)
{
return s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
}