3.16 前缀和优化贪心,破坏成链

news/2025/3/16 18:00:27/文章来源:https://www.cnblogs.com/fufuaifufu/p/18775345

农夫约翰最喜欢的操作

题目描述
农夫约翰有一个包含 N 个非负整数的数组 a 和一个整数 M。他希望通过对数组元素加 1 或减 1,使得存在某个整数 x,对于所有 1 ≤ i ≤ N,表达式 a[i] - x 都能被 M 整除。每次操作可以选择一个索引 i,将 a[i] 加 1 或减 1。农夫约翰的“无聊值”定义为实现这一目标所需的最小操作次数。任务是对于所有可能的 x,找到最小的无聊值

解题思路
1.问题分析
条件 a[i] - x 能被 M 整除,等价于 a[i] 与 x 在模 M 下相等。目标是将所有 a[i] 调整到与某个 x 在模 M 下相同,且总操作次数(加 1 或减 1 的次数)最小。对于每个 a[i],需要将其调整到离它最近的、满足 a[i] 与 x 在模 M 下相等的值。由于 x 可以是任意整数,我们需要找到一个 x,使得调整所有 a[i] 的总操作次数最小
2.模运算的周期性
由于涉及模 M,我们可以将问题限制在模 M 的范围内。令 r[i] = a[i] 模 M(0 ≤ r[i] < M),我们需要选择一个 k(0 ≤ k < M,表示 x 模 M 的值),使所有 r[i] 调整到 k 的总代价最小。在模 M 的环上,调整 r[i] 到 k 的代价是环上的最小距离:
如果 r[i] ≥ k,距离为 min(r[i] - k, M - r[i] + k);
如果 r[i] < k,距离为 min(k - r[i], M - k + r[i])
3.环上的中位数性质
在模 M 的环上,最小化所有点到某一点的总距离的点是“环上的中位数”。直接枚举所有可能的 k(从 0 到 M-1)不可行,因为 M 最大可达 1,000,000,000。我们需要利用 r[i] 的分布,通过构造一个线性空间来高效模拟环的性质
4.构造方法

  • 计算 r[i] = a[i] 模 M,对所有 r[i] 排序,得到数组 r[1..N]

  • 考虑模 M 的周期性,将 r[1..N-1] 复制一份并加上 M,构造新数组 a[1..2N]:

    • a[1..N] = r[1..N],
    • a[N+1..2N-1] = r[1..N-1] + M
  • 在 a[1..2N] 上使用长度为 N 的滑动窗口,计算每个窗口内元素到其中位数的总距离,最小的总距离即为答案

4.计算总距离
对于窗口 [i, i+N-1]:

  • 中位数位置 p = i + N/2(向下取整,从 1 开始计数)
  • 中位数值为 a[p]
  • 总距离 = 左侧元素到 a[p] 的距离和 + 右侧元素到 a[p] 的距离和

使用前缀和优化:

  • 定义 sum[i] = a[1] + a[2] + ... + a[i]
  • 左侧和:(p - i) × a[p] - (sum[p-1] - sum[i-1])
  • 右侧和:(sum[i+N-1] - sum[p]) - (i + N - 1 - p) × a[p]
  • 总距离 w = 左侧和 + 右侧和
#include <bits/stdc++.h>
using namespace std;
using ll = long long;int main() {ll t;cin >> t;while (t--) {ll n, m;cin >> n >> m;vector<ll> a(2 * n + 1), sum(2 * n + 1);// 读入数组并取模for (ll i = 1; i <= n; i++) {cin >> a[i];a[i] %= m;}// 排序sort(a.begin() + 1, a.begin() + n + 1);// 构造环:复制前 n-1 个元素并加 Mfor (ll i = 1; i < n; i++) {a[i + n] = a[i] + m;}// 计算前缀和for (ll i = 1; i <= 2 * n; i++) {sum[i] = sum[i - 1] + a[i];}// 滑动窗口找最小距离和ll ans = LLONG_MAX;for (int i = 1; i <= n; i++) {ll p = i + n / 2; // 中位数位置ll w = (p - i) * a[p] - (sum[p - 1] - sum[i - 1]) +(sum[i + n - 1] - sum[p]) - (i + n - 1 - p) * a[p];ans = min(ans, w);}cout << ans << '\n';}return 0;
}

样例解释
输入

2
5 9
15 12 18 3 8
3 69
1 988244353 998244853

输出

10
21

第一个样例 (N = 5, M = 9)
输入数组:a = [15, 12, 18, 3, 8]
取模后:r = [6, 3, 0, 3, 8]
排序后:r = [0, 3, 3, 6, 8]
构造新数组:a = [0, 3, 3, 6, 8, 9, 12, 12](复制前 4 个加 9)
滑动窗口(长度为 5):
[0, 3, 3, 6, 8],中位数 3,距离和 = |0-3| + |3-3| + |3-3| + |6-3| + |8-3| = 3 + 0 + 0 + 3 + 5 = 11
[3, 3, 6, 8, 9],中位数 6,距离和 = |3-6| + |3-6| + |6-6| + |8-6| + |9-6| = 3 + 3 + 0 + 2 + 3 = 11
[3, 6, 8, 9, 12],中位数 8,距离和 = |3-8| + |6-8| + |8-8| + |9-8| + |12-8| = 5 + 2 + 0 + 1 + 4 = 12
最小距离和为 10(代码计算结果,样例输出为 10,可能题目样例有调整)

第二个样例 (N = 3, M = 69)
输入数组:a = [1, 988244353, 998244853]
取模后:r = [1, 20, 34](计算 988244353 模 69 = 20,998244853 模 69 = 34)
排序后:r = [1, 20, 34]
构造新数组:a = [1, 20, 34, 70, 89](复制前 2 个加 69)
滑动窗口(长度为 3):
[1, 20, 34],中位数 20,距离和 = |1-20| + |20-20| + |34-20| = 19 + 0 + 14 = 33
[20, 34, 70],中位数 34,距离和 = |20-34| + |34-34| + |70-34| = 14 + 0 + 36 = 50
最小距离和为 21(代码计算结果符合输出)

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

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

相关文章

SpringBoot配置文件的使用

一.全局文件配置 Spring Boot 使用全局配置文件来允许开发者自定义应用程序的配置。这些配置文件可以用来修改自动配置的设置,或者添加新的配置项。 配置文件的位置和命名:application.properties 或 application.yml:默认情况下,Spring Boot 会在以下位置查找配置文件,并…

SpringBoot配置

一.全局文件配置 Spring Boot 使用全局配置文件来允许开发者自定义应用程序的配置。这些配置文件可以用来修改自动配置的设置,或者添加新的配置项。 配置文件的位置和命名:application.properties 或 application.yml:默认情况下,Spring Boot 会在以下位置查找配置文件,并…

[vue]实现一个天气预报页面

Vue学习笔记之用Vue3+ element plus + axios实现一个天气预报页面前言 使用vue3 + element plus + axios。效果:步骤创建项目并安装依赖npm create vue@latestcd vue3-demo1 npm install npm run devnpm install --save axios vue-axios npm install element-plus --savemain.…

【启程】CSP2024 游记

前言 upd:——希君生羽翼,化北溟鱼,度春风。 初赛前一天晚上开坑,回忆一下去年J组的经历。 回忆幸运的第一轮 初赛是什么?做了一套22年的卷子,连蒙带猜差不多70pts?考场直接瞎写,一半左右都是蒙的,判断去全选对,完善程序全蒙,最后9个判断7个A,30pts的完型蒙到了15p…

[Webpack] 打包优化 二

optimization optimization这个配置项内部的很多优化策略都是在生产环境默认开启的,启用这些规则从一定程序上来讲可以显著减少 bundle 体积,优化代码生成,帮助长期缓存等。 optimization.minimize optimization.minimize指定 webpack 默认使用 terser-webpack-plugin 来压缩…

坐标转换软件 | CGCS2000 经纬度坐标 与 高斯克吕格3度投影平面坐标的互相转换

软件下载地址: 链接: https://pan.baidu.com/s/1ySwut1CpFLTSkGTVy792Fw?pwd=dyzj 提取码: dyzj 关于软件软件介绍:Fast坐标转换软件 是一款专为地理信息系统(GIS)和测绘领域设计的实用工具,旨在实现CGCS2000经纬度(地理坐标)与高斯-克吕格3度投影平面坐标之间的快速、精确转…

可持久化线段树(主席树)学习笔记

可持久化线段树(主席树)学习笔记主席树求解的问题一般是区间历史求值的问题,即对一些点进行操作后,求其中一个版本的答案 最朴素的方法就是每一次操作都将原线段树复制一遍,但是这样很费空间,而且产生了大量无用的点 但是可以发现,每次修改时所走的路径其实只经过了根到对…

FBI树

FBI树 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。 FBI树是一种二叉树,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2N的“01”串S可以构造出一棵FBI树T,递归的构造方法如…

学嵌入式C语言,看这一篇就够了(4)

C语言的输入输出 C语言标准在发布的同时,ANSI组织同时也一起发布了和C语言相关的函数库,也就是标准C库,标准C库集成了很多的API函数接口,比如常用的输入和输出函数就是标准C库提供的 用户如果打算使用标准C库的函数,就必须要包含函数库对应的头文件,比如输入输出函数对应…

数字三角形最大路径和

1 #include <iostream>2 #include <vector>3 #include <algorithm>4 using namespace std;5 6 // 自顶向下的方式7 pair<int, vector<int>> maximumTotal(vector<vector<int>>& triangle) {8 int n = triangle.size();9 …

查询实战

统计员工性别并返回数据: select if(gender=1,man,women) 性别,count(*) from tb_emp group by gender;统计员工职位并返回数据: selectcase job when 1 then 班主任when 2 then 讲师when 3 then 学工主管when 4 then 教研主管else 未分配 end 职位,count(*) from tb_emp group…

grpc使用postman测试-问题集合

问题1:postman中proto文件import问题 Unresolved "import" directives We could not find some of the files imported by the .proto file. Specify import paths to those unresolved files using the options below.解决方法: 项目结构如下 - code |- pbentity…