前缀和个人见解(二)

2024-06-14 10:20
文章标签 前缀 个人见解

本文主要是介绍前缀和个人见解(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前缀和个人见解(二)

  • 二维前缀和数组
  • 构造二维前缀和数组
  • 二维前缀和数组的用途
    • 题目

二维前缀和数组

除了有一维前缀和,也可以推广到 二维。

假设我有一个二维数组,这些红色的点都是数组上的点。
在这里插入图片描述
其中用蓝色方框 选中的点 的前缀和 就是 下面的区域的数字之和。
在这里插入图片描述
假如是下面的这个点在这里插入图片描述

那么它的前缀和就是下面的区域的数字之和。
在这里插入图片描述


构造二维前缀和数组

接着我们来构造一个二维前缀和数组,也是利用递推的思路。

在这里插入图片描述
假设我们要求 紫色这个点的 二维前缀和。
在这里插入图片描述
我们可以先加上 这个点左边点的前缀和,也就是 绿色区域内数字之和。
在这里插入图片描述
然后再加上 紫色点 的 上边点 的前缀和,也就是 蓝色区域内的 数字之和。

此时会多加了一部分区域,也就是 蓝色和 绿色区域公共的部分,所以需要再减去 紫色点 的左上角点的前缀和。

当然最后得把我们紫色的值也给加上。

如果用代码写的话就是下面的公式。
在这里插入图片描述
当然 这里的 i 和 j 都不会取到 0,对于前缀和来说,留一层会方便会多。

二维前缀和数组的用途

那么构造了二维前缀和数组之后,它有什么用处呢?

其实跟一维的差不多,一维是求 一个区间内的和,那么二维就是求一个子矩阵的和。

在这里插入图片描述
比如我现在让你求这个 蓝色区域内 所有数之和,给你这个矩阵当中的 最左上角点的坐标和 最右下角点的坐标。

此时可以这么计算。
在这里插入图片描述

首先先加上 紫色点的前缀和。

在这里插入图片描述

然后减去 绿色点的前缀和。
在这里插入图片描述
再减去深蓝色的前缀和。

此时 深蓝色和 绿色公共的区域会 减去两次,则需要 再加上该区域,也就是下面 黄色点的前缀和。
在这里插入图片描述

此时 剩余的 就是我们蓝色 区域的 数字之和了。

公式如下:
在这里插入图片描述
其中 (x1, y1) (x2, y2) 分别为左上角和右下角的点的坐标。

接着我们来一起做做模版题。

题目

输入一个 n n n m m m 列的整数矩阵,再输入 q q q 个询问,每个询问包含四个整数 x 1 , y 1 , x 2 , y 2 x_1, y_1, x_2, y_2 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。

对于每个询问输出子矩阵中所有数的和。

输入格式

第一行包含三个整数 n , m , q n,m,q nmq

接下来 n n n 行,每行包含 m m m 个整数,表示整数矩阵。

接下来 q q q 行,每行包含四个整数 x 1 , y 1 , x 2 , y 2 x_1, y_1, x_2, y_2 x1,y1,x2,y2,表示一组询问。

输出格式

q q q 行,每行输出一个询问的结果。

数据范围

1 ≤ n , m ≤ 1000 1 \le n,m \le 1000 1n,m1000,
1 ≤ q ≤ 200000 1 \le q \le 200000 1q200000,
1 ≤ x 1 ≤ x 2 ≤ n 1 \le x_1 \le x_2 \le n 1x1x2n,
1 ≤ y 1 ≤ y 2 ≤ m 1 \le y_1 \le y_2 \le m 1y1y2m,
− 1000 ≤ 矩阵内元素的值 ≤ 1000 -1000 \le 矩阵内元素的值 \le 1000 1000矩阵内元素的值1000

输入样例:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

输出样例:

17
27
21

准备阶段:
在这里插入图片描述
其中 数组 a 存储题目给的原 数据,数组 s 为 a 的 前缀和 数组。

接着写 输入环节,注意是从 1 开始哦,猛猛记住这一点。

在这里插入图片描述

之后开始构造我们的 前缀和数组。

这里直接根据公式来就好了,注意公式一定要理解的去背,不能死记硬背。

在这里插入图片描述

在写这些公式的时候,你可以自己在脑海里想 区域,这样子会方便记忆公式。

在构造好前缀和数组后,接着就是面临 q 次询问。
在这里插入图片描述
对于每次询问,题目会每次给我们两个坐标,然后我们利用 刚才将的公式 直接输出就好啦。
在这里插入图片描述
完整代码如下:

#include <iostream>
using namespace std;const int N = 1010;
int n, m, q;
int a[N][N], s[N][N];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", &a[i][j]);for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + a[i][j];while (q--){int x1, y1, x2, y2;scanf("%d%d%d%d", &x1, &y1, &x2, &y2);printf("%d\n", s[x2][y2] - s[x2][y1-1] - s[x1-1][y2] + s[x1-1][y1-1]);}return 0;
}

这篇关于前缀和个人见解(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1060136

相关文章

【LeetCode热题100】前缀和

这篇博客共记录了8道前缀和算法相关的题目,分别是:【模版】前缀和、【模版】二维前缀和、寻找数组的中心下标、除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和。 #include <iostream>#include <vector>using namespace std;int main() {//1. 读取数据int n = 0, q = 0;ci

前缀和 — 利用前缀信息解决子数组问题

【前缀和的核心思想是预先处理数组来快速计算任意子数组的和,基本上用于数组和序列问题。】 前缀和算法具体步骤 构造前缀和数组: 给定一个数组nums,其前缀和数组prex定义为prex[i]表示为数组nums从起始位置到第i个位置的元素累加和。构建前缀和公式: p r e x [ i ] = n u m s [ i ] ( i = = 0 ) p r e x [ i ] = p r e x

每日一题~cf 970 div3 (A思维,B小模拟,C二分,D排列数建图成环,E 26个字母暴力+前缀和,F 逆元,G 数论gcd )

A 题意: 有 a 个1 ,b 个2.问是否能将这些数划分为两个数值相等的集合。 输出 YES 或者 NO —————— 问题等价于 将数组 分成两个数值相同的数组。所以sum 应该是偶数。也就是说 1 的个数是偶数。在i1的个数是偶数的情况下,将 2 分成两份,如果2 的个数是偶数,OK。如果是奇数那么需要1来补齐,如果1 的个数大于等于2那么可以补齐。(1 的个数是偶数,需要2个1来补齐,剩下

【数据结构-二维前缀和】力扣1504. 统计全 1 子矩形

给你一个 m x n 的二进制矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。 示例 1: 输入:mat = [[1,0,1],[1,1,0],[1,1,0]] 输出:13 解释: 有 6 个 1x1 的矩形。 有 2 个 1x2 的矩形。 有 3 个 2x1 的矩形。 有 1 个 2x2 的矩形。 有 1 个 3x1 的矩形。 矩形数目总共 = 6 + 2 + 3 + 1 +

Python高效实现Trie(前缀树)及其插入和查找操作

Python高效实现Trie(前缀树)及其插入和查找操作 在Python面试中,考官通常会关注候选人的编程能力、问题解决能力以及对Python语言特性的理解。Trie(前缀树)是一种高效的数据结构,广泛应用于字符串处理、自动补全、拼写检查等场景。本文将详细介绍如何实现一个Trie,并提供插入和查找操作,确保代码实用性强,条理清晰,操作性强。 1. 引言 Trie(前缀树)是一种树形数据结构,

Jaxb - 生成带命名空间和节点前缀的Xml的方式

一、生成带命名空间的Xml     Xml效果 <Order xmlns="http://www.xl.com.cn/msg">     Java代码 /*** Entity*/@XmlRootElement(name="Order", namespace="http://www.xl.com.cn/msg")public class Order{} 二、声明带前缀的命名空间

【UVa】10755 Garbage Heap 三维前缀和

题目分析:将前缀和应用到三维,求最大子矩阵。为S[x][y][z]数组中每个坐标保存从(0,0,0)到(x,y,z)范围内的子矩阵的元素和,最后用多次区间加减法可以得到需要的子矩阵的元素和,再用类似一维求最大连续和的方法求三维最大连续和。 代码如下: #include <cstdio>#include <cstring>#include <algorithm>using

【codeforces】gym 101138 K. The World of Trains【前缀和优化dp】

题目链接:K. The World of Trains 记录一个横着的前缀dp和以及斜着的前缀dp,复杂度 O(n2) O(n^2) #include <bits/stdc++.h>using namespace std ;typedef pair < int , int > pii ;typedef long long LL ;#define clr( a , x ) memset (

【C++ 前缀和 状态机dp】2826. 将三个组排序

本文涉及的基础知识点 C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C++动态规划 LeetCode2826. 将三个组排序 给你一个整数数组 nums 。nums 的每个元素是 1,2 或 3。在每次操作中,你可以删除 nums 中的一个元素。返回使 nums 成为 非递减 顺序所需操作数的 最小值。 示例 1: 输入:nums = [2,1,3,2,1] 输

JVM 的个人见解

著作权归作者所有。 商业转载请联系作者获得授权,非商业转载请注明出处。 作者:吴青海 链接:http://www.zhihu.com/question/27339390/answer/36511809 来源:知乎 java堆(JavaHeap) 1.用来存放对象的,几乎所有对象都放在这里,被线程共享的,或者说是被栈共享的 2.堆又可以分为新生代和老年代,实际还有一个区域叫永久代,但