【CSP考点回顾】前缀和数组

news2024/11/23 16:32:31

一、一维数组前缀和

前缀和算法是一种用于处理数组的技术,它可以快速计算任何连续子数组的和。适合在多次查询中需要求解多个范围和的情况。使用前缀和算法可以将每次求和的时间复杂度从 O(n) 降低到 O(1)。

  • 前缀和的思想是创建一个新数组 A r r Arr Arr p r e A r r [ i ] preArr[i] preArr[i] 记录 A r r [ 0... i − 1 ] Arr[0...i-1] Arr[0...i1] 的累加和,如图:

请添加图片描述

  • 那么,求索引区间 [ 1 , 4 ] [1,4] [1,4] 内所有元素之和,可以通过 p r e A r r [ 5 ] − p r e A r r [ 1 ] preArr[5]-preArr[1] preArr[5]preArr[1] 得出。这样,便只需要做一次减法运算,避免了每次进行 for 循环调用,时间复杂度为常数 O ( 1 ) O(1) O(1)

  • 前缀和算法广泛用于处理数组求和问题,特别是当需要多次求解不同子数组的和时,它可以大大减少计算时间。

  • 例如,班上有若干同学,每个同学有一个期末考试的成绩(满分100分),那么请实现输入任意一个分数段,返回有多少同学的成绩在这个分数段内。

vector<int>scores; // 存储所有分数
vector<int>cnt(100 + 1, 0); //满分为100
for (auto& it : scores) // 记录每个分数有多少同学
{
	cnt[it]++;
}
for (int i = 1; i < scores.size(); i++) // 构造前缀和
{
	cnt[i] += cnt[i - 1];
}
// 利用前缀和数组进行差分查询

二、二维数组的前缀和

二维数组的前缀和是前缀和概念在二维空间的扩展。这个技巧通常用于处理二维数组上的区域和查询,特别适合于频繁查询数组特定子矩阵(子区域)内元素的总和的情况

1.二维前缀和数组构建步骤:

  1. 初始化 p r e A r r 2 preArr2 preArr2 的所有元素为 0。

  2. 遍历原始二维数组 A r r 2 Arr2 Arr2,更新 p r e A r r 2 preArr2 preArr2 中的值。对于 p r e A r r 2 preArr2 preArr2 中的每个元素(位于 ( i , j ) (i, j) (i,j)),其值由以下元素决定:

    • 原数组 A r r 2 Arr2 Arr2 ( i − 1 , j − 1 ) (i - 1, j - 1) (i1,j1) 的值(因为 p r e A r r 2 preArr2 preArr2 A r r 2 Arr2 Arr2 多了一行和一列)。
    • p r e A r r 2 preArr2 preArr2 中上方 ( i − 1 , j ) (i - 1, j) (i1,j) 的前缀和。
    • p r e A r r 2 preArr2 preArr2 中左侧 ( i , j − 1 ) (i, j - 1) (i,j1) 的前缀和。
    • p r e A r r 2 preArr2 preArr2 中左上角 ( i − 1 , j − 1 ) (i - 1, j - 1) (i1,j1) 的前缀和,因为它被加了两次(在上方和左侧的和中),所以需要减去。
  3. p r e A r r 2 [ i ] [ j ] preArr2[i][j] preArr2[i][j] 的计算公式为:
    p r e A r r 2 [ i ] [ j ] = A r r 2 [ i − 1 ] [ j − 1 ] + p r e A r r 2 [ i − 1 ] [ j ] + p r e A r r 2 [ i ] [ j − 1 ] − p r e A r r 2 [ i − 1 ] [ j − 1 ] preArr2[i][j] = Arr2[i - 1][j - 1] + preArr2[i - 1][j] + preArr2[i][j - 1] - preArr2[i - 1][j - 1] preArr2[i][j]=Arr2[i1][j1]+preArr2[i1][j]+preArr2[i][j1]preArr2[i1][j1]

【注意】对于 p r e A r r 2 preArr2 preArr2 的第一行和第一列,我们将它们保持为 0,这样可以简化边界条件的处理。

2.使用二维前缀和数组数组:

  • 我们可以快速计算出原数组中任意子矩阵 ( x 1 , y 1 ) (x1, y1) (x1,y1) ( x 2 , y 2 ) (x2, y2) (x2,y2) 的和,通过以下公式:
    s u m = p r e A r r 2 [ x 2 + 1 ] [ y 2 + 1 ] − p r e A r r 2 [ x 1 ] [ y 2 + 1 ] − p r e A r r 2 [ x 2 + 1 ] [ y 1 ] + p r e A r r 2 [ x 1 ] [ y 1 ] sum = preArr2[x2 + 1][y2 + 1] - preArr2[x1][y2 + 1] - preArr2[x2 + 1][y1] + preArr2[x1][y1] sum=preArr2[x2+1][y2+1]preArr2[x1][y2+1]preArr2[x2+1][y1]+preArr2[x1][y1]
    这里 ( x 1 , y 1 ) (x1, y1) (x1,y1) 是子矩阵左上角的坐标, ( x 2 , y 2 ) (x2, y2) (x2,y2) 是子矩阵右下角的坐标。注意,因为 p r e A r r 2 preArr2 preArr2 的定义,我们需要使用加一的索引来引用原始 A r r 2 Arr2 Arr2 中的相应区域。

3.举例

原始二维数组 Arr2:

123
456
789

二维前缀和数组 preArr2:

0000
0136
051221
0122745

代码示例

#include <iostream>
#include <vector>

using namespace std;

int main() {
    // 定义初始二维数组 Arr2
    vector<vector<int>> Arr2 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

    // 获取数组的行数和列数
    int m = Arr2.size();
    int n = Arr2[0].size();

    // 构建二维前缀和数组 preArr2
    vector<vector<int>> preArr2(m + 1, vector<int>(n + 1, 0));
    for (int i = 1; i <= m; ++i) {
        for (int j = 1; j <= n; ++j) {
            preArr2[i][j] = Arr2[i - 1][j - 1] + preArr2[i - 1][j] + preArr2[i][j - 1] - preArr2[i - 1][j - 1];
        }
    }

    // 输出构建完成的二维前缀和数组
    for (int i = 0; i <= m; ++i) {
        for (int j = 0; j <= n; ++j) {
            cout << preArr2[i][j] << " ";
        }
        cout << "\n";
    }

    return 0;
}

本文部分内容参考自:【labuladong】前缀和/差分数组技巧精讲

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1493934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kamailio转发电话到目的地,目的返回失败时再转给其他IP

按图中这样测试&#xff1a; A---->kamailio------->B B返回480等失败错误码&#xff08;非200 OK&#xff09;&#xff0c;能进入failure_route[TOVOICEMAIL]&#xff0c;但是t_relay_to_udp执行失败。 好吧&#xff0c;说是&#xff1a;在 failure_route 中处理的是…

干货!Python函数定义与调用

1.函数定义 函数主要有两部分组成&#xff1a;声明部分和实现部分 def 是 define的简写&#xff0c;表示定义的意思 函数名类似于变量名&#xff0c;遵守标识符命名规则&#xff0c;尽量做到见名知意 ():里面放的是参数列表&#xff0c;参数列表中的参数可以为空 函数体:表…

Claude3荣登榜首,亚马逊云科技为您提供先行体验!

Claude3荣登榜首&#xff0c;亚马逊云科技为您提供先行体验&#xff01; 个人简介前言抢先体验关于Amazon BedrockAmazon Bedrock 的功能 Claude3体验教程登录Amazon Bedrock试用体验管理权限详细操作步骤1.提交应用场景详细信息2.请求模型的访问权限3.请求成功&#xff0c;开始…

Windows下Golang开发环境的安装

以下是在Windows操作系统下安装Go语言环境&#xff08;Golang&#xff09;的步骤。 请注意&#xff0c;安装步骤可能因Go的版本更新而有所变化&#xff0c;以下教程适用于撰写本文时的最新稳定版。 1、下载Go语言安装包 打开Go语言的官方下载页面&#xff1a;https://golang.go…

MySQL高可用性攻略:快速搭建MySQL主从复制集群 !

MySQL高可用性攻略&#xff1a;快速搭建MySQL主从复制集群 &#xff01; MySQL基础知识&#xff1a;介绍MySQL数据库的基本概念和常用命令&#xff0c;如何创建数据库、表、用户和权限管理等。 MySQL安装教程&#xff1a;Centos7 安装MySQL5.7.29详细安装手册 MySQL数据类型&…

Python 过滤函数filter()详解

一、过滤函数定义 它用于对容器中的元素进行过滤处理。 二、 过滤函数语法 filter(function,iterable) 参数function&#xff1a;提供过滤条件的函数&#xff0c;返回布尔型 参数iterable: 容器类型数据 三、过滤函数的应用场景 1、筛选符合条件的元素 需求&#xff1a;在列表…

VMware安装Ubuntu(保姆级)

VMware安装Ubuntu&#xff08;保姆级&#xff09; 文章目录 VMware安装Ubuntu&#xff08;保姆级&#xff09;一、镜像下载二、开始安装①&#xff1a;创建一个新的虚拟机②&#xff1a;开始安装③&#xff1a;安装 ssh 服务 提示&#xff1a;以下是本篇文章正文内容&#xff0…

第1题:两数之和

题目内容&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。…

“比特币刚破6.9万又套牢”?超31万人爆仓11.5亿美元!后市将如何发展?

时隔846天&#xff08;2021年11月10日&#xff09;之久&#xff0c;比特币终于在昨晚最高触及69080美元&#xff0c;再度创下历史新高&#xff0c;引发社群一片感慨&#xff1a;比特币再不亏欠任何人&#xff01; 怎料&#xff0c;比特币刚站上历史高点就急速下挫&#xff0c;一…

Linux基础——进程控制

1. 进程创建 在这之前我们曾了解过进程创建&#xff08;详见进程初识&#xff08;二&#xff09;&#xff09;&#xff0c;我们在这里对fork函数做一些补充 其实对于父子进程来说&#xff0c;若是有一方试图修改数据时&#xff0c;会向物理内存中申请一份新空间&#xff0c;并…

list链表的创建,排序,插入, test ok

1. 链表的建立&#xff0c;打印 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stack> #include <iostream> #include <string.h> #include <string>using namespace std;struct node {int data;s…

让运维无忧,实战解析巡检报告功能实现方案

随着大数据技术的演进和信息安全性需求的提升&#xff0c;数据规模的持续扩张为数据运维工作带来了严峻考验。面对海量数据所形成的繁重管理压力&#xff0c;运维人员面临效率瓶颈&#xff0c;而不断攀升的人力成本也使得单纯依赖扩充运维团队来解决问题变得不再实际可行。 由…

双体系Java学习之全路线图

Java路线图 此路线图是为了我以后的Java学习指明方向。 希望大家都能在Java的路线上越走越远&#xff01;努力学习&#xff01;&#xff01;

自动驾驶革命:解密端到端背后的数据、算力和AI奇迹

作者 |毫末智行数据智能科学家 贺翔 编辑 |祥威 最近&#xff0c;特斯拉FSD V12的发布引发了业界对端到端自动驾驶的热议&#xff0c;业界纷纷猜测FSD V12的强大能力是如何训练出来的。从马斯克的测试视频可以大致归纳一下FSD V12系统的一些核心特征&#xff1a; 训练数据&am…

FreeRTOS操作系统学习——空闲任务及其钩子函数

空闲任务 当 FreeRTOS 的调度器启动以后就会自动的创建一个空闲任务&#xff0c;这样就可以确保至少有一任务可以运行。但是这个空闲任务使用最低优先级&#xff0c;如果应用中有其他高优先级任务处于就绪态的话这个空闲任务就不会跟高优先级的任务抢占 CPU 资源。空闲任务还有…

图机器学习(1)--导论

0 CS224W概况 斯坦福大学CS224W课程&#xff1a;http://cs224w.stanford.edu/ 图机器学习的库&#xff1a; 为什么是图&#xff1f;图是描述和分析具有关系/交互的实体的通用语言。 1 图数据举例 复杂域具有丰富的关系结构&#xff0c;可以表示为关系图。 通过显式地建模关…

比瓴科技强势领跑软件开发安全领域,ASPM名列赛道第一

近日&#xff0c;斯元商业咨询正式发布2024首版「网安新兴赛道厂商速查指南&#xff5c;短名单精选」。比瓴科技入围七个赛道&#xff0c;其中ASPM、ASOC、SDL位居赛道第一。 应用安全态势管理&#xff08;ASPM&#xff09; 降低应用安全漏洞及数据泄露风险 比瓴在软件安全领…

seliunx 基础规则介绍

一 SELinux的状态 enforcing&#xff1a;强制&#xff0c;每个受限的进程都必然受限 permissive&#xff1a;允许&#xff0c;每个受限的进程违规操作不会被禁止&#xff0c;但会被记录于审计日志 disabled&#xff1a;禁用 二 相关命令 getenforce: 获取selinux当前状…

SDWAN专线,解决银行网络搭建痛点

金融行业的不断发展和数字化转型&#xff0c;银行网络的搭建和管理面临着诸多挑战和痛点。SD-WAN&#xff08;Software-Defined Wide Area Network&#xff0c;软件定义广域网&#xff09;专线作为一种创新的网络解决方案&#xff0c;为银行解决了诸多网络搭建痛点&#xff0c;…

Hadoop集群配置与管理指南

目录 前言一、Hadoop集群配置历史服务器二、配置日志的聚集三、集群启动/停止方式总结四、编写Hadoop集群常用脚本五、常用端口号说明最后 前言 这篇文章内容覆盖了Hadoop集群中一些重要且常用的配置和管理任务。首先&#xff0c;我们将介绍如何配置Hadoop集群的历史服务器&am…