【前缀和】数的前n项,子矩阵的和

前缀和

2021.11.10

有一串数列,a1,a2,a3,a4.....在数组a[n]中(一定要从第一项开始存)

我们再启用一个数组s[n]用来存放a[n]的前n项和,由于s[n]是全局变量,所以默认初始化s[0]=0

此时如果查询并操作前n项和的话,时间复杂度为o(1)

代码段

#include<bitsstdc++.h>
using namespace std;
typedef long long L;
const int N = 1e6 + 10;
int n,m;
int a[N],tmp[N],s[N]; 
//前缀和
int main()
{
	scanf_s("%d%d", &n, & m);
	for (int i = 1; i <= n; i++)scanf_s("%d", &a[i]);

	for (int i = 1; i <= n; i++)s[i] = s[i - 1] + a[i];
	while (m--)
	{
		int l, r;
		scanf_s("%d%d", &l, &r);
		printf("%d\n", s[r] - s[l - 1]);
	}
	return 0;
}

子矩阵的和

2021.11.11

 

如图所示,在求前缀和数组时有两个重要公式

第一个是计算s[i,j]的公式

s[i,j] =s[i-1,j]+s[i,j-1]-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]

详细公式证明可以参考 (主要依靠数学归纳法证明)

容斥原理

容斥原理_百度百科在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。https://baike.baidu.com/item/%E5%AE%B9%E6%96%A5%E5%8E%9F%E7%90%86/10146840?fr=aladdin

 代码段

#include<bitsstdc++.h>
using namespace std;
const int N = 1e6 + 10;
const int M = 1010;
int n, m, q;
int a[N], tmp[N], s[N];
int a1[M][M], s1[M][M];
//前缀和数组
int main()
{

	scanf("%d%d%d", &n, &m, &q);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			scanf("%d", &a1[i][j]);
	//初始化前缀和数组
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			s1[i][j] = s1[i - 1][j] + s1[i][j - 1] - s1[i - 1][j - 1] + a1[i][j];
	while (q--)
	{
		int x1, y1, x2, y2;
		scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
		printf("%d\n", s1[x2][y2] - s1[x2][y1 - 1] - s1[x1 - 1][y2] + s1[x1 - 1][y1 - 1]);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/nathanqian123/article/details/121250377