当前位置:首页 > C++目录 > 正文内容

【算法】前缀和与差分(3)二维数组前缀和

亿万年的星光3年前 (2022-12-10)C++目录2952

0.前言

前面的一篇文章,介绍了一维数组的前缀和,这篇文章中,介绍一下二维数组的前缀和

1.定义

二维数组的前缀和就是按照二维数组求和。公式如下:

那二维前缀和中一个f[i][j]表示的意思就是
以(1,1)为左上角以(i,j)为右下角这个矩阵里面数的和,可以用下面的这个图表示

f[i][j]就是红色框的部分。

举个例子:

1 2 4 3
5 1 2 4
6 3 5 9

如果按照公式进行计算,结果是:

1  3   7  10
6  9   15  22
12  18   29  45

把上面这个图扩大

我们要求(i,j), (i,j)可以由两部分块构成 (i-1,j) 和 (i,j-1)。

不过需要注意,

  1. 如果单纯把(i-1,j)和(i,j-1)加起来,那么有一块是重复加了,就是(i-1,j-1)这一块(图中灰色区域),所以要减去它。

  2. 这个矩阵还不完整,缺少了途中红色那块,所以我们需要单独把(i,j)这个点加起来。


  3. 假设第i行第j列对应的数组为aij  ,对应的二维前缀和为sumij 。基于容斥原理,那么

sumi,j = sum i-1,j + sum i,j-1  - sum i-1,j-1   + ai,j

sum[i,j] =sum[i-1,j] + sum[i,j-1] -sum[i-1,j-1] +a[i,j]

【参考代码】

#include <bits/stdc++.h>
 
using namespace std;
 
const int MAXN = 1e3+2;
const int MAXM = 1e3+2;
int sum[MAXN][MAXM] = {};
 
int main() {
	int n,m,r,c;
	cin>>n>>m;//>>r>>c;
	
	int data;
	for (int i=1; i<=n; i++) {
		for (int j=1; j<=m; j++) {
			cin >> data;
			sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+data;
		}
	}
	
	for (int i=1; i<=n; i++) {
		for (int j=1; j<=m; j++) {
			cout << sum[i][j] << " ";
		}
		cout << endl;
	}
	
	return 0;
}







扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

排序算法中的一些分类

排序算法中的一些分类

一、比较和非比较的排序二、时间复杂度和稳定性如何界定一个排序算法是否是稳定的?假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=...

最小生成树(1)

最小生成树(1)

一、定义一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出...

C++读取磁盘文件

0.前言简单介绍一下C++读取文件的基本操作。关键技术:freopen() 文件的打开函数 FILE *fp fp=fopen(文件名,使用文件方式) 例如: fp...

2023 CSP 山东地区分数线汇总

地区CSP-XCSP-JCSP-S烟台556648.5临沂516416青岛476753淄博446547.5...

进制转换类问题汇总

二进制转十进制十进制转二进制十进制转M进制(M一般小于16)M进制转十进制M进制和N进制互转...

取模运算总结——数论

编程竞赛有相当一部分题目的结果过于庞大,整数类型无法存储,往往只要求输出取模的结果。例如(a+b)%p,若a+b的结果我们存储不了,再去取模,结果显然不对,我们为了防止溢出,可以先分别对a取模,b取模...