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

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

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

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







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

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

分享给朋友:

相关文章

指针(三):指针与函数

1.交换的例子#include<iostream> #include<cstdio> #include<cstring> using namespa...

信息学奥赛中文件流的写法

信息学奥赛中文件流的写法

头文件#include<cstdio>也可以用万能头格式如下:int main(){ freopen("xxxx.in","r",st...

C++小项目——实时钟表

C++小项目——实时钟表

0.前言在很多游戏中,我们要使用时间,这个时间一个是系统当前的时间,一个是服务器给你的时间。这篇文章我们尝试做一个模拟时钟。效果图如下1.任务分解1.首先我们尝试使用easyx来画一个。基本框架如下:...

【STL】二分查找函数 lower_bound 和 upper_bound

一、 lower_bound【功能】在数组a中从a[begin]开始到a[end - 1]按照cmp函数来比较进行二分查找第一个大于等于k的数的地址,如果有第一个大于等于k的数则返回该数的地...

【数论】同余定理与同余方程

定义同余定理是数论中的一个重要概念。它的定义是这样的:给定一个整数m,如果两个整数a和b满足(a-b)能够被m整除,即(a-b)/m 得到一个整数,那么就成整数a和b对模m同余,记作a≡b(mod m...

【题解】围圈报数(约瑟夫问题)

【题解】围圈报数(约瑟夫问题)

【题目描述】有n个人依次围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始报数,数到第m个热呢又出列,... ,如此反复到所有的人全部出列为止。设n个人的编号分别为1,2,......