当前位置: 首页 > news >正文

算法每日双题精讲 —— 前缀和(【模板】一维前缀和,【模板】二维前缀和)

在算法竞赛与日常编程中,前缀和是一种极为实用的预处理技巧,能显著提升处理区间和问题的效率。今天,我们就来深入剖析一维前缀和与二维前缀和这两个经典模板。

一、【模板】一维前缀和

题目描述

给定一个长度为 n n n 的整数数组 a a a,我们需要完成以下两个任务:

  1. 预处理数组,得到前缀和数组。
  2. 能够快速查询数组中任意区间 [ l , r ] [l, r] [l,r] 0 ≤ l ≤ r < n 0 \leq l \leq r < n 0lr<n)内所有元素的和。

算法原理

一维前缀和的核心思想是预先计算数组中每个位置之前所有元素的总和。设前缀和数组为 s s s,其中 s [ i ] s[i] s[i] 表示数组 a a a 中前 i i i 个元素的和( i i i 1 1 1 开始),那么有递推公式:
[s[i] = s[i - 1]+a[i - 1]]
这里 s [ 0 ] = 0 s[0]=0 s[0]=0,是为了方便处理边界情况。

当我们需要查询区间 [ l , r ] [l, r] [l,r] 的和时,根据前缀和的性质,该区间的和可以通过 s [ r + 1 ] − s [ l ] s[r + 1]-s[l] s[r+1]s[l] 快速得到。这是因为 s [ r + 1 ] s[r + 1] s[r+1] 包含了前 r + 1 r + 1 r+1 个元素的和, s [ l ] s[l] s[l] 包含了前 l l l 个元素的和,两者相减就得到了区间 [ l , r ] [l, r] [l,r] 的和。

在这里插入图片描述

在这里插入图片描述

C++ 代码实现

#include <iostream>
#include <vector>using namespace std;// 计算一维前缀和数组
vector<int> calculatePrefixSum(const vector<int>& a) {int n = a.size();vector<int> s(n + 1, 0);for (int i = 1; i <= n; ++i) {s[i] = s[i - 1] + a[i - 1];}return s;
}// 查询区间 [l, r] 的和
int querySum(const vector<int>& s, int l, int r) {return s[r + 1] - s[l];
}int main() {vector<int> a = {1, 2, 3, 4, 5};vector<int> s = calculatePrefixSum(a);int l = 1, r = 3;cout << "The sum of the interval [" << l << ", " << r << "] is: " << querySum(s, l, r) << endl;return 0;
}

复杂度分析

  • 时间复杂度:计算前缀和数组的时间复杂度为 O ( n ) O(n) O(n),因为需要遍历数组一次。每次查询区间和的时间复杂度为 O ( 1 ) O(1) O(1),这使得在多次查询的场景下,一维前缀和算法具有很高的效率。
  • 空间复杂度:需要额外的长度为 n + 1 n + 1 n+1 的数组来存储前缀和,因此空间复杂度为 O ( n ) O(n) O(n)

二、【模板】二维前缀和

题目描述

给定一个 m × n m \times n m×n 的二维整数矩阵 A A A,我们要完成以下任务:

  1. 预处理矩阵,得到二维前缀和矩阵。
  2. 能够快速查询矩阵中任意子矩阵 [ ( x 1 , y 1 ) , ( x 2 , y 2 ) ] [(x_1, y_1), (x_2, y_2)] [(x1,y1),(x2,y2)] 0 ≤ x 1 ≤ x 2 < m 0 \leq x_1 \leq x_2 < m 0x1x2<m 0 ≤ y 1 ≤ y 2 < n 0 \leq y_1 \leq y_2 < n 0y1y2<n)内所有元素的和。

算法原理

对于二维前缀和,我们定义 S [ i ] [ j ] S[i][j] S[i][j] 表示矩阵 A A A 中从左上角 ( 0 , 0 ) (0, 0) (0,0) 到右下角 ( i − 1 , j − 1 ) (i - 1, j - 1) (i1,j1) 这个子矩阵内所有元素的和( i i i j j j 1 1 1 开始)。其递推公式如下:
S [ i ] [ j ] = S [ i − 1 ] [ j ] + S [ i ] [ j − 1 ] − S [ i − 1 ] [ j − 1 ] + A [ i − 1 ] [ j − 1 ] S[i][j]=S[i - 1][j]+S[i][j - 1]-S[i - 1][j - 1]+A[i - 1][j - 1] S[i][j]=S[i1][j]+S[i][j1]S[i1][j1]+A[i1][j1]
这里减去 S [ i − 1 ] [ j − 1 ] S[i - 1][j - 1] S[i1][j1] 是为了避免重复计算。

当查询子矩阵 [ ( x 1 , y 1 ) , ( x 2 , y 2 ) ] [(x_1, y_1), (x_2, y_2)] [(x1,y1),(x2,y2)] 的和时,公式为:
s u m = S [ x 2 + 1 ] [ y 2 + 1 ] − S [ x 1 ] [ y 2 + 1 ] − S [ x 2 + 1 ] [ y 1 ] + S [ x 1 ] [ y 1 ] sum = S[x_2 + 1][y_2 + 1]-S[x_1][y_2 + 1]-S[x_2 + 1][y_1]+S[x_1][y_1] sum=S[x2+1][y2+1]S[x1][y2+1]S[x2+1][y1]+S[x1][y1]

在这里插入图片描述

在这里插入图片描述

C++ 代码实现

#include <iostream>
#include <vector>using namespace std;// 计算二维前缀和矩阵
vector<vector<int>> calculateTwoDPrefixSum(const vector<vector<int>>& A) {int m = A.size();int n = A[0].size();vector<vector<int>> S(m + 1, vector<int>(n + 1, 0));for (int i = 1; i <= m; ++i) {for (int j = 1; j <= n; ++j) {S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + A[i - 1][j - 1];}}return S;
}// 查询子矩阵 [(x1, y1), (x2, y2)] 的和
int queryTwoDSum(const vector<vector<int>>& S, int x1, int y1, int x2, int y2) {return S[x2 + 1][y2 + 1] - S[x1][y2 + 1] - S[x2 + 1][y1] + S[x1][y1];
}int main() {vector<vector<int>> A = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};vector<vector<int>> S = calculateTwoDPrefixSum(A);int x1 = 0, y1 = 0, x2 = 1, y2 = 1;cout << "The sum of the sub - matrix [(" << x1 << ", " << y1 << "), (" << x2 << ", " << y2 << ")] is: "<< queryTwoDSum(S, x1, y1, x2, y2) << endl;return 0;
}

复杂度分析

  • 时间复杂度:计算二维前缀和矩阵需要两层嵌套循环遍历矩阵,时间复杂度为 O ( m × n ) O(m \times n) O(m×n)。每次查询子矩阵和的时间复杂度为 O ( 1 ) O(1) O(1),这使得在多次查询子矩阵和的场景下,二维前缀和算法非常高效。
  • 空间复杂度:需要额外的 ( m + 1 ) × ( n + 1 ) (m + 1)\times(n + 1) (m+1)×(n+1) 大小的矩阵来存储二维前缀和,因此空间复杂度为 O ( m × n ) O(m \times n) O(m×n)

通过以上的讲解和代码实现,我们可以看到前缀和算法在处理区间和与子矩阵和问题时的强大威力。它通过预处理的方式,将原本可能需要 O ( n ) O(n) O(n) O ( m × n ) O(m\times n) O(m×n) 时间复杂度的查询操作优化到了 O ( 1 ) O(1) O(1),在实际应用中能显著提升程序的性能。希望大家能够熟练掌握这两个模板,并在后续的算法学习和实践中灵活运用。

相关文章:

算法每日双题精讲 —— 前缀和(【模板】一维前缀和,【模板】二维前缀和)

在算法竞赛与日常编程中&#xff0c;前缀和是一种极为实用的预处理技巧&#xff0c;能显著提升处理区间和问题的效率。今天&#xff0c;我们就来深入剖析一维前缀和与二维前缀和这两个经典模板。 一、【模板】一维前缀和 题目描述 给定一个长度为 n n n 的整数数组 a a a&…...

Maui学习笔记- SQLite简单使用案例02添加详情页

我们继续上一个案例&#xff0c;实现一个可以修改当前用户信息功能。 当用户点击某个信息时&#xff0c;跳转到信息详情页&#xff0c;然后可以点击编辑按钮导航到编辑页面。 创建项目 我们首先在ViewModels目录下创建UserDetailViewModel。 实现从详情信息页面导航到编辑页面…...

VMware 中Ubuntu无网络连接/无网络标识解决方法【已解决】

参考文档 Ubuntu无网络连接/无网络标识解决方法_ubuntu没网-CSDN博客 再我们正常使用VMware时&#xff0c;就以Ubuntu举例可能有时候出现无网络连接&#xff0c;甚至出现无网络标识的情况&#xff0c;那么废话不多说直接上教程 环境&#xff1a;无网络 解决方案&#…...

完美世界前端面试题及参考答案

如何设置事件捕获和事件冒泡? 在 JavaScript 中,可以通过addEventListener方法来设置事件捕获和事件冒泡。该方法接收三个参数,第一个参数是事件类型,如click、mousedown等;第二个参数是事件处理函数;第三个参数是一个布尔值,用于指定是否使用事件捕获机制。当这个布尔值…...

新时代架构SpringBoot+Vue的理解(含axios/ajax)

文章目录 引言SpringBootThymeleafVueSpringBootSpringBootVue&#xff08;前端&#xff09;axios/ajaxVue作用响应式动态绑定单页面应用SPA前端路由 前端路由URL和后端API URL的区别前端路由的数据从哪里来的 Vue和只用三件套axios区别 引言 我是一个喜欢知其然又知其所以然的…...

代理模式 -- 学习笔记

代理模式学习笔记 什么是代理&#xff1f; 代理是一种设计模式&#xff0c;用户可以通过代理操作&#xff0c;而真正去进行处理的是我们的目标对象&#xff0c;代理可以在方法增强&#xff08;如&#xff1a;记录日志&#xff0c;添加事务&#xff0c;监控等&#xff09; 拿一…...

gif动画图像优化,相同的图在第2,4,6帧中重复出现,会增加图像体积吗?

对于 GIF 图像&#xff0c;情况与 Git 文件存储有所不同。GIF 是一种图像格式&#xff0c;其体积主要取决于图像的内容、颜色数量、优化设置等因素。如果在 GIF 动画中&#xff0c;相同的图像在第 2、4、6 帧中重复出现&#xff0c;是否会增加图像体积&#xff0c;取决于以下几…...

Harmony Next 跨平台开发入门

ArkUI-X 官方介绍 官方文档&#xff1a;https://gitee.com/arkui-x/docs/tree/master/zh-cn ArkUI跨平台框架(ArkUI-X)进一步将ArkUI开发框架扩展到了多个OS平台&#xff1a;目前支持OpenHarmony、Android、 iOS&#xff0c;后续会逐步增加更多平台支持。开发者基于一套主代码…...

阿里巴巴Qwen团队发布AI模型,可操控PC和手机

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

android 音视频系列引导

音视频这块的知识点自己工作中有用到&#xff0c;一直没有好好做一个总结&#xff0c;原因有客观和主观的。 客观是工作太忙&#xff0c;没有成段时间做总结。 主观自己懒。 趁着这次主动离职拿了n1的钱&#xff0c;休息一下&#xff0c;对自己的人生做一下总结&#xff0c;…...

STM32调试手段:重定向printf串口

引言 C语言中经常使用printf来输出调试信息&#xff0c;打印到屏幕。由于在单片机中没有屏幕&#xff0c;但是我们可以重定向printf&#xff0c;把数据打印到串口&#xff0c;从而在电脑端接收调试信息。这是除了debug外&#xff0c;另外一个非常有效的调试手段。 一、什么是pr…...

基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结

title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付&#xff08;CI/CD&#xff09;流程里&#xff0c;及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...

Vue.js组件开发-实现导出PDF文件可自定义添加水印及水印样式方向

使用 Vue 实现导出 PDF 文件并添加水印&#xff0c;同时支持设置水印样式、方向和自定义水印内容。 步骤 安装依赖&#xff1a;使用 html2canvas 将 HTML 内容转换为 canvas&#xff0c;使用 jspdf 生成 PDF 文件。创建 Vue 组件&#xff1a;在组件中实现水印生成、HTML 转 c…...

css中的animation

css的animation animation是一个综合属性,是animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state, and animation-timeline这些属性的简写 不过在…...

四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)

四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09; 文章目录 四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09;2.hash 哈希表常用指令(详细讲解说明)2.1 hset …...

基于Springboot + vue实现的洗衣店订单管理系统

“前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能学习网站” &#x1f496;学习知识需费心&#xff0c; &#x1f4d5;整理归纳更费神。 &#x1f389;源码免费人人喜…...

用 Scoop 优雅管理 Windows 软件:安装、配置与使用全指南

本篇将主要讲讲如何用「Scoop」优雅管理 Windows 软件&#xff1a;安装、配置与使用全指南 一、Scoop 是什么&#xff1f; Scoop 是一款专为 Windows 设计的命令行软件包管理工具&#xff0c;它能让你像 Linux 系统一样通过命令快速安装、更新和卸载软件。其核心优势包括&…...

深度学习中常用的评价指标方法

深度学习中常用的评价指标方法因任务类型&#xff08;如分类、回归、分割等&#xff09;而异。以下是一些常见的评价指标&#xff1a; 1. 分类任务 准确率&#xff08;Accuracy&#xff09; 定义&#xff1a;正确预测的样本数占总样本数的比例。 公式&#xff1a;AccuracyTPT…...

多协议网关BL110钡铼6路RS485转MQTT协议云网关

多协议网关BL110钡铼6路RS485转MQTT协议云网关是一款集成了多种通信协议的工业级网关设备&#xff0c;专为物联网&#xff08;IoT&#xff09;应用设计。该网关能够将RS485总线设备的数据转化为MQTT协议&#xff0c;通过网络传输到云平台&#xff0c;实现远程监控和数据管理。以…...

Nginx 安装配置指南

Nginx 安装配置指南 引言 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c;同时也可以作为 IMAP/POP3/SMTP 代理服务器。由于其稳定性、丰富的功能集以及低资源消耗而被广泛应用于各种场景。本文将为您详细介绍 Nginx 的安装与配置过程。 系统要求 在安装 Nginx 之…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...