前缀和

202 阅读2分钟

前缀和定义

前缀和是一个数组的某项下标之前(包括此项元素)的所有数组元素的和。
原数组: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];

二位数组‘.png
代码

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];
}