当前位置:首页 > C++知识 > 正文内容

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

亿万年的星光3年前 (2022-12-10)C++知识2758

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







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

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

分享给朋友:

相关文章

C++整型的数据范围

数据类型标识符占字节数数值范围数值范围短整型short [int]2(16位)-32768~32767-2^15 到2^15  -1整型[long] int4(32位)-...

【题解】最短路径问题

【题目描述】平面上有n个点(n≤100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现...

多重背包问题

一、问题定义有 n 种物品,每种物品有三个属性:重量 weight[i](正整数)价值 value[i](正整数)数量 count[i](正整数,表示...

2023 CSP 山东地区分数线汇总

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

组合数的写法

前面我们写过 全排列和排列数 等。这篇文章。我们写一下组合数。例题:从n个数中,选出m个,一共有多少种不同的选法?这是一道典型的组合数公式。我们直接用dfs公式肯定会出现重复的。#include<...

质数(素数)的判断

一、定义法// 1 定义法(除了1和他本身之外,没有任何一个数能被整除)(试除法) bool is_prime3(unsigned long lon...