最小差值

news/2025/4/1 0:35:08/文章来源:https://www.cnblogs.com/onlyblues/p/18799205

最小差值

题目描述

给你一个由 $n$ 个整数组成的数组 $\{a_1,a_2,\dots,a_n\}$,以及一个由 $m$ 个整数组成的数组 $\{b_1,b_2,\dots,b_m\}$,现在我们需要寻找一个最小的整数 $k$,满足 $-2 \times 10^9 \leq k \leq 2 \times 10^9$,使得下式达到最小:$$\left \lvert \bigg(\sum\limits_{i=1}^{n}\left \lvert a_i - k \right \rvert\bigg) - \bigg(\sum\limits_{j=1}^{m}\left \lvert b_j - k \right \rvert\bigg) \right \rvert$$

直接输出满足条件的最小 $k$ 即可。

输入描述:

第一行输入两个整数 $n,m\left(1\leq n,m\leq 10^6\right)$ 代表数组 $a$ 中的元素个数、数组 $b$ 中的元素个数。

第二行输入 $n$ 个整数 $a_1,a_2,\dots,a_n\left(-10^9\leq a_i\leq 10^9\right)$。

第三行输入 $m$ 个整数 $b_1,b_2,\dots,b_m\left(-10^9\leq b_j\leq 10^9\right)$。

输出描述:

直接输出满足条件的最小 $k$ 即可。

示例1

输入

5 5
1 2 3 4 5
1 2 3 4 5

输出

-2000000000

说明

在这个样例中,我们会发现,$k$ 的取值不影响最后的答案,所以选择最小的 $k=-2\times 10^9$ 即可。

示例2

输入

5 3
1 5 9 3 6
2 5 10

输出

3

说明

在这个样例中,$k=3$ 时,有:$$\begin{aligned}\begin{aligned}\bigg(\sum\limits_{i=1}^{5}\left \lvert a_i - 3 \right \rvert\bigg) &= \left \lvert 1 - 3 \right \rvert + \left \lvert 5 - 3 \right \rvert + \left \lvert 9 - 3 \right \rvert + \left \lvert 3 - 3 \right \rvert + \left \lvert 6 - 3 \right \rvert \\&= 2 + 2 + 6 + 0 + 3 \\&= 13\end{aligned}\\\begin{aligned}\bigg(\sum\limits_{j=1}^{3}\left \lvert b_j - 3 \right \rvert\bigg) &= \left \lvert 2 - 3 \right \rvert + \left \lvert 5 - 3 \right \rvert + \left \lvert 10 - 3 \right \rvert \\&= 1 + 2 + 7 \\&= 10\end{aligned}\end{aligned}$$

综上,式子的答案为 $\left \lvert 13 - 10 \right \rvert = 3$,我们可以证明,无法再找到一个 $-2\times 10^9\leq k\leq 3$,使得式子的值 $\le 3$。

 

解题思路

  由于排序不影响结果,为了方便先对数组 $a$ 和 $b$ 从小到大排序。我们可以枚举每一个 $k$ 来求式子的最小值,但细想一下会发现,当 $k$ 落在某个范围内时,式子的结果是不变的。具体来说,我们把数组 $a$ 和 $b$ 进行合并同时从小到大排序,得到数组 $p$。对于任意 $k \in [p_i, p_{i+1}]$ 时,此时 $k$ 必然是 $a$ 的两个相邻元素之间的某个值,同时也是 $b$ 的两个相邻元素之间的某个值,此时 $\bigg(\sum\limits_{i=1}^{n}\left \lvert a_i - k \right \rvert\bigg)$ 和 $\bigg(\sum\limits_{j=1}^{m}\left \lvert b_j - k \right \rvert\bigg)$ 的结果都相同,因此式子不变。

  这启发我们只需关注每一段 $[p_i, p_{i+1}], \, (1 \leq i < n+m)$ 即可。假设当前枚举到第 $i$ 段 $[p_i, p_{i+1}]$,为了描述把式子中的 $k$ 换成 $x$,此时 $x \, (p_i \leq x \leq p_{i+1})$ 应该取值多少,才能使得式子有最小值?假设 $a$ 中有 $c_a$ 个元素小于等于 $x$(意味着 $n - c_a$ 个元素大于 $x$),$b$ 中有 $c_b$ 个元素小于等于 $x$(意味着 $m - c_b$ 个元素大于 $x$)。此时式子的结果等于

\begin{align*}
&\left \lvert \bigg(\sum\limits_{i=1}^{n}\left \lvert a_i - x \right \rvert\bigg) - \bigg(\sum\limits_{j=1}^{m}\left \lvert b_j - x \right \rvert\bigg) \right \rvert \\
= &\left \lvert \sum\limits_{i=1}^{c_a}{x-a_i} + \sum\limits_{i=c_a+1}^{n}{a_i-x} - \left( \sum\limits_{i=1}^{c_b}{x-b_i} + \sum\limits_{i=c_b+1}^{m}{b_i-x} \right) \right \rvert \\
= &\left \lvert c_ax - \sum\limits_{i=1}^{c_a}{a_i} + \sum\limits_{i=c_a+1}^{n}{a_i} - (n-c_a)x - \left( c_bx - \sum\limits_{i=1}^{c_b}{b_i} + \sum\limits_{i=c_b+1}^{m}{b_i} - (m-c_b)x \right) \right \rvert \\
= &\left \lvert \left(c_a - (n - ca) + (m - c_b) - c_b\right)x + \left(- \sum\limits_{i=1}^{c_a}{a_i} + \sum\limits_{i=c_a+1}^{n}{a_i}- \sum\limits_{i=1}^{c_b}{b_i} + \sum\limits_{i=c_b+1}^{m}{b_i} \right) \right \rvert \\
\end{align*}

  记 $k = \left(c_a - (n - ca) + (m - c_b) - c_b\right)$,$b = \left(- \sum\limits_{i=1}^{c_a}{a_i} + \sum\limits_{i=c_a+1}^{n}{a_i}- \sum\limits_{i=1}^{c_b}{b_i} + \sum\limits_{i=c_b+1}^{m}{b_i} \right)$,因此就是求折线 $|kx+b|$ 的最小值。

  只需分情况讨论即可,首先是两个端点 $p_i$ 和 $p_{i+1}$。然后是可能的最小点 $kx+b = 0 \Rightarrow x = \frac{-b}{k}$,由于 $x$ 是整数,因此需要考虑以下三个取值,$\left \lfloor \frac{-b}{k} \right \rfloor-1$、$\left \lfloor \frac{-b}{k} \right \rfloor$、$\left \lfloor \frac{-b}{k} \right \rfloor +1$(同时需要保证 $p_i \leq x \leq p_{i+1}$)。

  AC 代码如下,时间复杂度为 $O((n+m)\log{(n+m)})$:

#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N = 1e6 + 5, M = N * 2;int a[N], b[N];
LL sa[N], sb[N];
array<int, 2> p[M];int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n, m;cin >> n >> m;for (int i = 1; i <= n; i++) {cin >> a[i];}for (int i = 1; i <= m; i++) {cin >> b[i];}sort(a + 1, a + n + 1);sort(b + 1, b + m + 1);for (int i = 1; i <= n; i++) {sa[i] = sa[i - 1] + a[i];}for (int i = 1; i <= m; i++) {sb[i] = sb[i - 1] + b[i];}int sz = 0;for (int i = 1; i <= n; i++) {p[sz++] = {a[i], 0};}for (int i = 1; i <= m; i++) {p[sz++] = {b[i], 1};}p[sz++] = {int(-2e9), -1};p[sz++] = {int(2e9), -1};sort(p, p + sz);LL mn = 1e18, ret;for (int i = 0, ca = 0, cb = 0; i + 1 < sz; i++) {if (!p[i][1]) ca++;else if (p[i][1] == 1) cb++;LL k = ca - (n - ca) + (m - cb) - cb, b = sa[n] - 2 * sa[ca] + 2 * sb[cb] - sb[m];auto get = [&](LL x) {if (x < p[i][0] || x > p[i + 1][0]) return;if (abs(k * x + b) < mn) {mn = abs(k * x + b);ret = x;}};get(p[i][0]);if (k) {get(-b / k - 1);get(-b / k);get(-b / k + 1);}get(p[i + 1][0]);}cout << ret;return 0;
}

 

参考资料

  小白月赛113题解:https://ac.nowcoder.com/discuss/1480037

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

银行网点加钞间作业人数异常报警系统

银行网点加钞间作业人数异常报警系统检测银行网点加钞间区域内作业人数,对超过设定人数阈值,进行预警。加钞间少于2人进行报警,规范员工操作,落实银行制度。自助环境区域、防护舱内区域重点关注大于等于2人,预防案件发生。通过人脸识别比对系统,对加钞间非授权人员进行检…

RAGFlow部署

参照https://eogee.com/article/detail/17进行 其中主要就是放开ragflow/docker/.env文件中的RAGFLOW_IMAGE华为云镜像地址 修改ragflow/docker/docker-compose.yml文件中的端口 Q:访问网页注册登录无反应 打开控制台看是报了502的错误 A:确保mysql,redis,minio,es等先启动,然…

多模态AI核心技术:CLIP与SigLIP技术原理与应用进展

近年来,人工智能领域在多模态表示学习方面取得了显著进展,这类模型通过统一框架理解并整合不同数据类型间的语义信息,特别是图像与文本之间的关联性。在此领域具有里程碑意义的模型包括OpenAI提出的CLIP(Contrastive Language-Image Pre-training,对比语言-图像预训练)和…

在岗人数分析报警摄像机

在岗人数分析报警摄像机采用AI算法,通过大量真实的场景样本训练后,能够在各种应用场景下及时准确地对场景中人员数量的分析统计预警。在岗人数分析报警摄像机是可以实时分析一个指定值班域内的人员数量,当所监视区域的值班人员数量少于设定的阀值时摄像机输出开关量信号,可…

工厂车间在岗人数分析预警系统

工厂车间在岗人数分析预警系统基于AI人工智能分析技术,将车间生产区域员工在岗人数进行管理预警,可以实现对厂区的全面覆盖,全天候保障厂区生产安全,建立完善长效的安全生产运营机制。在岗人数分析预警系统嵌入AI人员离岗分析算法,可对车间生产区域内人员的数量进行精确分…

虚拟机vmware16 安装centos8.5 你全流程和详细配置

因为centos8.5 不能使用他自己的源,所以新装的系统默认不能安装软件,需要做一些配置 其二。部份虚拟机新装的不能连网,所以我将今天安装的流程记录以下,如果正好有别人需要,可以看一下我安装的流程第一步,如果不能上网配置。先装虚拟机配成桥接试试,可能是默认上nat 那…

FaceBook OAuth2登录配置

应用必须上架才能正式使用FaceBook developers 后台添加应用配置https://developers.facebook.com 创建应用,應用程式設定 -》 添加IOS包名,添加安卓包名, 應用程式編號,應用程式密鑰 对应服务端配置: FacebookLoginAppId FacebookLoginAppSecret 首次登录访问提示错误,错…

itdog-ping

地址 https://www.itdog.cn/ping/ 概览作者:mohistH 出处:https://www.cnblogs.com/pandamohist/ 本文版权归作者和博客园共有,谢绝一切形式的转载,否则将追究法律责任。

某客户RAID出现Multi-bit ECC error错误

某客户反馈,BMC带外有Major级别的告警,告警内容如下可以看出SEL指向RAID卡,产生告警时间为2024年11月14日。检查RAID卡日志,找2024年11月14号发生的事件。从RAID卡事件可以看出来RAID卡从2024年11月9号到2024年11月14号,5天内并没有记录任何日志(如下图)一直到2024年11月…

直播软件怎么开发,Redis触发扩容的两种情况

直播软件怎么开发,Redis触发扩容的两种情况1、如果没有fork子进程在执行RDB或者AOF的持久化,一旦满足ht[0].used >= ht[0].size,此时触发扩容;2、如果有fork子进程在执行RDB或者AOF的持久化时,则需要满足ht[0].used > 5 * ht[0].size,此时触发扩容。下面将结合源码…

怎么快速干净拆焊直插元件的方法成都承接电路板设计

我处提供优质的单片机、PLC、电路板、控制器/箱、仪器仪表、机电设备或系统、自动化、工控、传感、数据采集、自控系统、控制系统、物联网、电子产品、软件、APP开发设计定制服务(业务www点yonko-tech点com),在做项目的时候,拆除电路板上的元件也是有的事情,拆元件说难不难…

flutter:用http库下载文件

一,安装第三方库 地址: https://pub.dev/packages/http 编辑pubspec.yaml: dependencies:flutter:sdk: flutterpath_provider: ^2.1.5http: ^1.3.0 然后点击 pub get 二,代码: import package:flutter/material.dart; import package:http/http.dart show get; import packa…