AcWing 802. 区间和(离散化算法,python)
本篇博客详细讲解一下离散化知识点,通过讲解和详细列题带大家掌握离散化。
题目:
原题链接:https://www.acwing.com/problem/content/description/804/
假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。
现在,我们首先进行 n 次操作,每次操作将某一位置 x 上的数加 c。
接下来,进行 m 次询问,每个询问包含两个整数 l 和 r,你需要求出在区间 [l,r] 之间的所有数的和。
输入格式
第一行包含两个整数 n 和 m。
接下来 n 行,每行包含两个整数 x 和 c。
再接下来 m 行,每行包含两个整数 l 和 r。
输出格式
共 m 行,每行输出一个询问中所求的区间内数字和。
数据范围
− 1 0 9 ≤ x ≤ 1 0 9 -10^9≤x≤10^9 −109≤x≤109,
1 ≤ n , m ≤ 1 0 5 1≤n,m≤10^5 1≤n,m≤105,
− 1 0 9 ≤ l ≤ r ≤ 1 0 9 −10^9≤l≤r≤10^9 −109≤l≤r≤109,
− 10000 ≤ c ≤ 10000 −10000≤c≤10000 −10000≤c≤10000
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5
什么是前缀和?(会此算法可以跳过不看)
一维前缀和&一维差分(下篇讲解二维前缀和&二维差分)(超详细,python版,其他语言也很轻松能看懂)
什么是离散化?
本题猛的一看似乎就是一道前缀和的模板题,但需要注意到这里所谓的“坐标”的范围较大,范围在 − 1 0 9 ≤ x ≤ 1 0 9 -10^9≤x≤10^9 −109≤x≤109,为了存下被修改的点的数据,如果将它们的坐标作为数组的下标就需要开一个 2 ∗ 1 0 9 2*10^9 2∗109大小的数组,肯定会爆内存,况且这里的坐标还有负值,不方便进行存储。
所以要提出一个新的能方便快捷存数据的算法——离散化。
离散化的内存优化思路是只存储那些被用到的点(在这里指的是“被加了值的点”以及“要查询区间的两个端点”),然后利用一些较小的值来代替它们的坐标进行索引,并最终保持它们的相对位置。
举个例子:对于“被用到的点”只有四个:1、11、886、320001,如果用传统的存储方式要开1~320001个连续的存储空间,但其实没必要,因为会浪费掉了很多没有用到的空间。其实它们的相对位置可以分别用1(1)、2(11)、3(886)、4(320001)来替代,进而只需要开1~4个连续的存储空间并且全部用上;反观此题的数据量,操作次数决定要存点的个数,n、m均小于等于 1 0 5 10^5 105,所以“被用到的点”最多为 n + 2 m = 3 ∗ 1 0 5 n + 2m =3 *10^5 n+2m=3∗105个 ,也即内存从 2 ∗ 1 0 9 2 * 10^9 2∗109优化到了 3 ∗ 1 0 5 3 * 10^5 3∗105,整整少了4个数量级!
因此,点的存储位置变为连续,但其表示的值却为离散,故而称其被离散化。
如何离散化?(题解)
为了能够将较大的坐标点及其该坐标点上的数值存储下来,就需要使用两个映射:
- total_num(数组):用来存放题目中用到的坐标点,也就是题中的x, l, r,初始值为空数组。total_num数组表示坐标到相对位置的映射:先将题目中输入样例给出的坐标点全都放入(append)total_num数组后,进行一遍排序和去重,这样就必能保证小的坐标位置在前,大坐标在后,此时下标就是它们新的“相对位置”。
- a(数组):用来存放离散化后的坐标的值的变化,初始范围为 3 ∗ 1 0 5 + 10 3 * 10^5 + 10 3∗105+10 (n + 2m 最大为 3 ∗ 1 0 5 3 * 10^5 3∗105)。表示相对位置到坐标点上的数值的映射:拿到坐标点的相对位置new_x后,a[new_x] += c就存下了坐标点的数据了。
这里还需要定义add_num数组用来存放整数(x, c),定义query_num数组,用来存放询问的区间(l, r)
再定义a的前缀和数组s,预处理完后利用s[r] - s[l - 1]就能得到 [l,r] 区间和了。
下面来详细讲解一下各数组的作用和具体实现方法:
首先初始化各个数组,其中a数组和s数组的长度为 3 ∗ 1 0 5 + 10 3 * 10^5 + 10 3∗105+10,值为0,其余数组初始为空。
total_num数组为何除了要存被改动点的坐标x还要存储查询区间的两端点l和r呢?
主要是因为后续要通过s[r] - s[l - 1]来获取到区间和,而必须将它们在坐标轴上的情况也存下来才能知道这个区间的情况,因而它也算作“被用到的点”。
那么被改动点(x, c)和查询端点(l, r)分别还要再放到add_num和query_num里方便处理。
具体的存储情况还可以下图为例:

这里还有一个难点就是如何进行离散化?也就是如何把total_num数组映射到a数组上?这里需要借用二分来进行插入操作,二分的初始左端点 l 为0,右端点 r 为total_num数组的长度减一,mid = (l+r) // 2,传入参数是x(这里的x是toal_num里的数值,需要对total_num进行遍历并挨个把total_num中的值映射到a数组中),只要total_num[mid] <= x,那么r = mid 否则 l = mid + 1,最后返回值是 l + 1。
为什么返回的是 l + 1 呢?因为a数组和s数组的下标是从1开始的(下标从1开始是方便处理前缀和),所以这里需要进行+1操作。
下面给出详细代码和注释:
# 读取输入的n和m,分别表示添加操作的数量和查询操作的数量
n, m = map(int, input().split())
N = 300010
a = [0] * N
s = [0] * N
# 用于存储添加操作的列表,每个元素是一个元组,包含要添加的数值x和对应的增量c
add_num = []
# 用于存储查询操作的列表,每个元素是一个元组,包含查询的区间左端点l和右端点r
query_num = []
# 用于存储所有出现过的坐标
total_num = [] # 读取n个添加操作
for i in range(n): x, c = map(int, input().split()) add_num.append((x, c)) total_num.append(x) # 将x添加到total_num中 # 读取m个查询操作
for i in range(m): l, r = map(int, input().split()) query_num.append((l, r)) total_num.append(l) # 将l添加到total_num中 total_num.append(r) # 将r添加到total_num中 # 对total_num进行排序并去重,得到所有唯一出现过的数值
total_num = list(set(sorted(total_num))) # 定义一个查找函数,用于在total_num中找到数值x映射到a的位置(索引从1开始)
def find(x): l = 0 r = len(total_num) - 1 while l < r: mid = (l + r) // 2 if total_num[mid] >= x: r = mid else: l = mid + 1 return l + 1# 对每个添加操作进行处理,将增量c添加到对应的位置
for x, c in add_num: new_x = find(x) # 找到total_num中x映射到a的位置a[new_x] += c # 将增量c添加到a数组的对应位置 # 计算前缀和数组s
for i in range(1, N): s[i] = s[i - 1] + a[i] # 前缀和公式# 对每个查询操作进行处理,计算并输出区间和
for l, r in query_num: xl = find(l) xr = find(r) print(s[xr] - s[xl - 1])
相关文章:
AcWing 802. 区间和(离散化算法,python)
本篇博客详细讲解一下离散化知识点,通过讲解和详细列题带大家掌握离散化。 题目: 原题链接:https://www.acwing.com/problem/content/description/804/ 假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。 现在,…...
【网页设计】CSS 盒子模型
目标 能够准确阐述盒子模型的 4 个组成部分能够利用边框复合写法给元素添加边框能够计算盒子的实际大小能够利用盒子模型布局模块案例能够给盒子设置圆角边框能够给盒子添加阴影能够给文字添加阴影 1. 盒子模型 页面布局要学习三大核心, 盒子模型, 浮动 和 定位. 学习好盒子模…...
如何通过构建对应的api服务器使Vue连接到数据库
一、安装数据库驱动 在后端安装 MySQL 数据库驱动,比如在 Node.js 环境中可以使用 mysql2 包来连接 MySQL 数据库。在项目目录下运行以下命令安装: npm install mysql2或者使用 yarn: yarn add mysql2二、创建数据库连接模块 创建一个专门…...
新手给视频加字幕的方法有哪些?4种加字幕方法推荐!
在视频制作中,字幕不仅是传递信息的重要手段,还能增强视频的观感和专业性。对于新手来说,如何给视频添加字幕可能是一个挑战。本文将介绍字幕的类型、推荐添加字幕的工具,以及详细添加字幕方法,帮助新手轻松掌握视频字…...
Oracle实际需要用到但常常被忽略的函数
1、Oracle中nvl()与nvl2()函数 函数nvl(expression1,expression2)根据参数1是否为null返回参数1或参数2的值; 函数nvl2(expression1,expression2,expression3)根据参数1是否为null返回参数2或参数3的值 【函数格式】:nvl(expression1,expression2) 若…...
代码随想录算法训练营Day23
局部最优——>全局最优&无反例,试试贪心 455.分发饼干 力扣题目链接:. - 力扣(LeetCode) class Solution {public int findContentChildren(int[] g, int[] s) {Arrays.sort(s);Arrays.sort(g);int gindex0;int count0;…...
vue使用table实现动态数据报表(行合并)
<template><div class"previewTable"><h2>***项目研发数据报告</h2><table id"previewTable" width"100%"><tr><th>项目名称</th><td colspan"6">{{ resultData.proName }}<…...
YARN调度原理详解
YARN(Yet Another Resource Negotiator)是 Hadoop 集群的资源管理和作业调度框架,它的设计旨在更好地管理和调度 Hadoop 集群中的资源。YARN 解决了传统 Hadoop MapReduce 中资源管理与作业调度紧耦合的问题,使得不同类型的计算任…...
Go-知识泛型
Go-知识泛型 1. 认识泛型1.1 不使用泛型1.2 使用泛型 2. 泛型的特点2.1 函数泛化2.2 类型泛化 3. 类型约束3.1 类型集合3.2 interface 类型集合3.2.1 内置interface类型集合3.2.2 自定义interface类型集合3.2.2.1 任意类型元素3.2.2.2 近似类型元素3.2.2.3 联合类型元素 3.2.3 …...
Qt 如何 发送与解析不定长报文以及数组不定长报文
文章目录 割方式一,采用QDataStream 解析,可直接设定大小端解析,无需自己转换方式二,采用结构体字节对齐方式解析发送接收方割 方式一,采用QDataStream 解析,可直接设定大小端解析,无需自己转换 需要注意的是结构体定义要去掉字节对齐,否则会崩溃,因为由自定义数据结…...
Rust默认使用UTF-8编码来解析源代码文件。如果在代码中包含无法用UTF-8编码表示的字符,编译器会报错!
文章目录 Rust默认编码示例在ANSI编码下中文显示正常的代码在UTF-8编码下将显示不正常在编译时,Rust使用UTF-8编码来解析代码,发现无法用UTF-8编码表示的字符,于是编译器报错 Rust默认编码 Rust 语言默认使用 UTF-8 编码来解析源代码文件。如…...
【jeston】torch相关环境安装
参考:玩转NVIDIA Jetson (25)— jetson 安装pytorch和torchvision 我的jeston信息: torch install 安装环境 conda create -n your_env python3.8 conda activate your_envpytorch_for_jeston 安装.whl文件 验证࿱…...
[CR]厚云填补_大型卫星影像去云数据集
AllClear: A Comprehensive Dataset and Benchmark for Cloud Removal in Satellite Imagery Abstract 卫星图像中的云对下游应用构成了重大挑战。当前云移除研究的一个主要挑战是缺乏一个全面的基准和一个足够大和多样化的训练数据集。为了解决这个问题,我们引入了…...
Langchain CharacterTextSplitter无法分割文档问题
在使用Langchain的文档分割器时,使用CharacterTextSplitter拆分文档是,发现返回的文档根本没有变化,即使设置了chunk_size,返回的大小也不符合参数设置。 CharacterTextSplitter设置了150,但是根本没有处理࿰…...
ros service不走是为什么
在ROS(Robot Operating System)中,如果ROS服务(Service)没有正常工作,可能有多种原因。你可以检查以下几点来排查问题: 服务是否正确启动 首先,确保服务节点已经启动并注册了相应的…...
量子计算机的原理与物理实现
量子计算机的原理与物理实现很复杂 指导性原则 首先思考制备一台量子计算机需要些什么? 需要量子比特——二能级量子系统。除了量子计算机需要满足一些物理特性,它还必须要把量子比特绘制到某种初态上,以及测量系统的输出态。 而实验上的挑战…...
SQL Server 常用关键词语法汇总
一、函数 1.1 CAST CAST ( expression AS data_type [ ( length ) ] )expression: 这是你想要转换的数据或表达式。data_type: 目标数据类型,比如 INT, VARCHAR, DATE 等等。(length): 对于某些数据类型(如 CHAR, VARCHAR, BINARY, VARBINARYÿ…...
软件测试工程师面试整理 —— 操作系统与网络基础!
在软件测试中,了解操作系统和网络基础知识对于有效地进行测试工作至关重要。无论是在配置测试环境、调试网络问题,还是在进行性能测试和安全测试时,这些知识都是不可或缺的。 1. 操作系统基础 操作系统(Operating System, OS&am…...
网络安全防御策略:通过限制IP访问提升服务器安全性
标题:网络安全防御策略:通过限制IP访问提升服务器安全性 摘要: 在网络安全领域,服务器被入侵是一场严重的事故。一旦发生这种情况,除了立即采取措施恢复系统外,还需要加强后续的安全防护措施。本文将探讨为…...
Multiprocessing出错没有提示was skipped without notice in python
这个问题可以通过打印返回结果解决。 解决方法 比如 Pool.apply_async(csdnKuangXiaoHU, args=(p, DestFile))改成 Result = Pool.apply_async(csdnKuangXiaoHU, args=...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
