(蓝桥杯)使用差分数组和前缀和解决区间更新问题——倒水

server/2025/1/17 13:03:02/

题目描述

在一个桌子上摆放了 n 个杯子,每个杯子中有一定量的水。小 A 同学负责向杯子中倒水,他总共倒了 k 次,每次会向从第 L 个杯子到第 R 个杯子中添加 P 毫升的水(注意:水只可能增加,不可能减少)。

请问小 A 同学倒了 k 次水之后, n 个杯子每个杯子有多少毫升的水。

输入

第一行包含两个整数 n 和 k。

第二行包含 n 个整数,表示一开始每个杯子中水的毫升数。

接下来 k 行,每行包含三个整数 L,R,P,表示一次操作。

数据范围

1≤n,k≤100000。

1≤L≤R≤n,0≤P≤1000。

杯子中水的初始量在 [0,1000] 的范围内。

本题数据上保证所有的杯子在加水之后,水量值仍然在 int 范围内

输出

共一行,包含 n 个整数,表示最终 n 个杯子每个杯子有多少毫升的水。

样式

输入:

8 3
1 2 10 8 1 5 1 1
7 8 12
1 8 4
2 3 12 

输出

5 18 26 12 5 9 17 17

知识点

前缀和

前缀和是一种预处理技术,通过预先计算数组的前缀和,可以快速地求出任意区间的和。具体来说,对于一个数组 a,其前缀和数组 prefix 定义为:

prefix[i]=a[0]+a[1]+⋯+a[i]

通过前缀和数组,我们可以快速计算任意区间 [l, r] 的和:

sum(l,r)=prefix[r]−prefix[l−1]

例如,给定数组 a = [1, 2, 3, 4, 5],其前缀和数组为 prefix = [1, 3, 6, 10, 15]。如果要计算区间 [1, 3] 的和,可以直接计算 prefix[3] - prefix[0] = 10 - 1 = 9

差分

差分是一种用于处理区间更新问题的技术。差分数组 diff 定义为:

diff[i]=a[i]−a[i−1]

通过差分数组,我们可以高效地进行区间更新。例如,要将数组 a 的区间 [l, r] 中的每个元素增加 p,只需更新差分数组的两个位置:

diff[l]+=p

diff[r+1]−=p

前缀和与差分在处理数组问题时非常高效。前缀和可以将区间求和的时间复杂度从 O(n) 降低到 O(1),而差分可以将区间更新的时间复杂度从 O(n) 降低到 O(1)。这两种技术在处理大规模数据时尤其有用,能够显著提高算法的效率。

例如,在处理多次区间更新和查询的问题时,可以先使用差分数组进行所有更新操作,然后通过一次前缀和计算还原出最终的数组,从而避免了每次更新都遍历整个数组的开销。

题解

我们将使用差分数组和前缀和来高效地解决这个问题。差分数组可以帮助我们快速进行区间更新,而前缀和可以将差分数组还原为最终的数组。

1. 读取输入

首先,我们需要从标准输入读取输入数据。

python">import sys# 读取输入
n, k = map(int, sys.stdin.readline().split())
a = [int(i) for i in sys.stdin.readline().split()]
2. 构建差分数组

差分数组 b 的第 i 个元素表示 a[i] - a[i-1]。我们可以通过遍历数组 a 来构建这个数组。差分数组的第 0 个元素初始化为 a[0]

python">b = [0] * (n + 10)
for i in range(n):if i == 0:b[i] = a[i]else:b[i] = a[i] - a[i - 1]
3. 进行区间更新

对于每次区间更新操作 l, r, p,我们只需要更新差分数组 b 的两个位置:b[l-1]b[r]

python">for i in range(k):l, r, p = map(int, sys.stdin.readline().split())b[l - 1] += pb[r] -= p
4. 计算前缀和

通过计算差分数组 b 的前缀和,我们可以还原出最终的数组 a

python">for i in range(n):if i > 0:b[i] += b[i - 1]sys.stdout.write(str(b[i]))if i < n - 1:  # 在最后一个元素后不加空格sys.stdout.write(" ")
sys.stdout.write("\n")  # 最后换行
完整代码
python">import sys# 读取输入
n, k = map(int, sys.stdin.readline().split())
a = [int(i) for i in sys.stdin.readline().split()]# 构建差分数组
b = [0] * (n + 10)
for i in range(n):if i == 0:b[i] = a[i]else:b[i] = a[i] - a[i - 1]# 进行区间更新
for i in range(k):l, r, p = map(int, sys.stdin.readline().split())b[l - 1] += pb[r] -= p# 计算前缀和并输出结果
for i in range(n):if i > 0:b[i] += b[i - 1]sys.stdout.write(str(b[i]))if i < n - 1:  # 在最后一个元素后不加空格sys.stdout.write(" ")
sys.stdout.write("\n")  # 最后换行
总结

通过使用差分数组和前缀和,我们可以高效地进行区间更新操作。差分数组允许我们在 O(1) 时间内完成每次区间更新,而前缀和则可以在 O(n) 时间内还原出最终的数组。这种方法的时间复杂度为 O(n + k),适用于大规模数据。


http://www.ppmy.cn/server/159091.html

相关文章

Jmeter 简单使用、生成测试报告(一)

一、下载Jmter 去官网下载&#xff0c;我下载的是apache-jmeter-5.6.3.zip&#xff0c;解压后就能用。 二、安装java环境 JMeter是基于Java开发的&#xff0c;运行JMeter需要Java环境。 1.下载JDK、安装Jdk 2.配置java环境变量 3.验证安装是否成功&#xff08;java -versio…

Mysql数据库索引

Spring Data JPA建立索引所使用的语法 Entity Table(name "user",indexes {Index(name "idx_user_username", columnList "username"),Index(name "idx_user_email_status", columnList "email, status")},uniqueCon…

Cisco ASA nat配置示例-NAT的顺序

需要10.248.1.1 访问internet时转换为outside接口IP object network 10.248.1.1 host 10.248.1.1 nat (inside,outside) source dynamic 10.248.1.1 interface 有时会遇到nat配置正确&#xff0c;但业务不通的情况 。 这时可以通过packet-tracer命令查看数据流在哪一步出问题…

初学者如何用 Python 写第一个爬虫?

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…

doris:导入概览

Apache Doris 提供了多种导入和集成数据的方法&#xff0c;您可以使用合适的导入方式从各种源将数据导入到数据库中。Apache Doris 提供的数据导入方式可以分为四类&#xff1a; 实时写入&#xff1a;应用程序通过 HTTP 或者 JDBC 实时写入数据到 Doris 表中&#xff0c;适用于…

docker 与K8s的恩怨情仇

Docker 和 Kubernetes&#xff08;通常简称为 K8s&#xff09;是容器化和容器编排领域的两大重要工具&#xff0c;它们在技术生态中扮演着不同的角色&#xff0c;并且有着密切的关系。虽然有时候人们会讨论它们之间的关系&#xff0c;但实际上它们更多的是互补而不是对立。下面…

分布式 IO 模块:引领立体车库迈向智能化新时代

在城市空间愈发珍贵的当下&#xff0c;立体车库作为高效利用空间的停车解决方案&#xff0c;正日益普及。而明达技术MR30分布式 IO 模块的应用&#xff0c;如同为立体车库注入了智能 “芯” 动力&#xff0c;让停车变得更加便捷、高效、智能。 MR30分布式 IO 模块&#xff0c;作…

代码随想录算法训练营第十三天(2)|541. 反转字符串II

文档讲解&#xff1a;代码随想录 难度&#xff1a;easy 附&#xff1a;冲 passion&#xff01;&#xff01;&#xff01;passion&#xff01;&#xff01;&#xff01;passion&#xff01;&#xff01;&#xff01; 541. 反转字符串II 力扣题目链接(opens new window) 给定一…