【每日一题】补档 CF1065 C. Make It Equal | 思维 | 中等

ops/2024/10/21 9:46:28/

题目内容

原题链接

给定一个长度为 n n n 的数组 a a a ,每次操作可以选择一个数 x x x ,将所有大于 x x x 的数都下降为 x x x ,一次操作的下降总代价为 s s s ,要求 s ≤ k s\leq k sk ,问需要多少次操作使得数组 a a a 的所有数都相同。

数据范围

  • 1 ≤ n ≤ 2 ⋅ 1 0 5 1\leq n\leq 2\cdot 10^5 1n2105
  • n ≤ k ≤ 1 0 9 n\leq k\leq 10^9 nk109
  • 1 ≤ a i ≤ 2 ⋅ 1 0 5 1\leq a_i\leq 2\cdot 10^5 1ai2105

题解

朴素做法

首先使得所有数都相同,则使得所有值都成为 m i n ( a ) min(a) min(a)

所以考虑怎么将所有数都变成 m i n ( a ) min(a) min(a)

先对 a a a 排序,然后从最大的数开始依次将前面大的数往小了降。

从大的值开始往下依次枚举,看每次的 k k k 可以将前面多少数统一下降为一个数。

因为值域很小,所以可以直接枚举值域,这样的时间复杂度是 O ( m a x ( a ) + n ) O(max(a)+n) O(max(a)+n)

优化做法

如果值域很大,是否有与值域无关的做法。

其实这种题本身就应该值域无关,考虑当前最大的数为 c u r cur cur ,有 c n t cnt cnt 个值为 c u r cur cur 的数,下一步变成一个大于 a [ j ] a[j] a[j] 的最小的数 n x t nxt nxt

那么就有 ( c u r − n x t ) × c n t (cur-nxt)\times cnt (curnxt)×cnt 的代价将所有的 c u r cur cur 变成 n x t nxt nxt

所有相邻元素如果差距过大,考虑将统一下降的部分额外操作出来,保证我们每次循环的开始都是先用一个操作将整体的数做下降。

这样可以保证一次遍历就可以将所有元素都变成 m i n ( a ) min(a) min(a)

时间复杂度: O ( n log ⁡ n ) O(n\log n) O(nlogn)

代码

#include <bits/stdc++.h>
using namespace std;typedef long long ll;void solve() {int n, k;cin >> n >> k;vector<int> a(n);for (int i = 0; i < n; ++i) cin >> a[i];sort(a.begin(), a.end(), greater<>());if (a.back() == a.front()) {cout << "0\n";return;}// 一次 k 能够支撑多少元素下降ll ans = 0;ll pre = 0;ll cnt = 0;ll cur = -1;for (int i = 0; i < n; ++i) {ll s = k;// 第一个 s 到某个 a[j - 1]int j = i;while (j < n && pre - cnt * a[j] <= s) {cur = a[j];pre += a[j];cnt += 1;j += 1;}// pre 肯定是一个统一的值if (j > i) {s -= pre - cnt * a[j - 1];// 然后把剩下部分给整了ll dec = s / cnt;cur = a[j - 1] - dec;pre = cur * cnt;ans += 1;}// pre -> a[j - 1]if (j < n) {ll single_op = k / cnt;ll single_decrease = single_op * cnt;ll cnt_op = (cur - a[j] - 1) * cnt / single_decrease;ans += cnt_op;cur = cur - cnt_op * single_op;pre = cur * cnt;}i = j - 1;}cout << ans << "\n";
}int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);int T = 1;//cin >> T;while (T--) {solve();}return 0;
}

http://www.ppmy.cn/ops/18983.html

相关文章

MB6F-ASEMI新能源专用整流桥MB6F

编辑&#xff1a;ll MB6F-ASEMI新能源专用整流桥MB6F 型号&#xff1a;MB6F 品牌&#xff1a;ASEMI 封装&#xff1a;MBF-4 最大重复峰值反向电压&#xff1a;600V 最大正向平均整流电流(Vdss)&#xff1a;1A 功率(Pd)&#xff1a;小功率 芯片个数&#xff1a;4 引脚数…

FSMC读取FPGA的FIFO

一、硬件说明 FSMC配置 单片机的代码如下&#xff1a; #define VALUE_ADDRESS_AD1 (__IO uint16_t *)0x60400000while (1){if(!HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_8)) //数据非空{data *(__IO uint16_t *)VALUE_ADDRESS_AD1;data2 *(__IO uint16_t *)VALUE_ADDRESS_AD1…

用Excel做一个功能完备的仓库管理系统

1 基本设计思路 用到的Excel技术&#xff1a;sumif, vlookup, 表格(table)。基本思路&#xff1a;在有基础的商品、仓库等信息的情况下&#xff0c;对商品的每一个操作都有对应的单据&#xff0c;然后再汇总统计。标识&#xff1a;为了在不同的维度统计数量&#xff0c;各单据…

Blender边操作

1.边的细分 Subdivide -选中一条边&#xff0c;右键&#xff0c;细分 2.边的滑移&#xff0c;Edge Slide -选中一条边 -菜单&#xff0c;边-滑移边线 其中&#xff0c;滑移时&#xff0c;是以两侧的邻边为轨道&#xff0c;滑移的边线无法越过轨道尽头 3.边的删除 -选中一…

自动化爬虫工具:you-get安装与使用

Windows下的安装命令&#xff1a; pip install you-get linux下的安装命令&#xff1a; pip3 install you-get 下载完成后&#xff0c;我们可以看到如下的警告&#xff0c;意思就是这个工具并未被添加到环境变量中&#xff0c;如果我们想在命令行中直接调用&#xff0c;需要…

React【Day4】

路由快速上手 1. 什么是前端路由 一个路径 path 对应一个组件 component 当我们在浏览器中访问一个 path 的时候&#xff0c;path 对应的组件会在页面中进行渲染 2. 创建路由开发环境 # 使用CRA创建项目 npm create-react-app react-router-pro# 安装最新的ReactRouter包 …

Kotlin语法快速入门-函数(4)

Kotlin语法快速入门-函数&#xff08;4&#xff09; 文章目录 Kotlin语法快速入门-函数&#xff08;4&#xff09;四、函数1、函数定义2、infix关键字3、参数省略4、函数类型参数5、多参数--vararg 四、函数 1、函数定义 fun 函数名(参数: 类型) &#xff1a;返回值类型{//函…

【golang学习之旅】深入理解字符串string数据类型

系列文章 【golang学习之旅】报错&#xff1a;a declared but not used 【golang学习之旅】Go 的基本数据类型 目录 系列文章使用示例string的底层数据结构关于字符串复制字符串是不可变的如何高效的进行字符串拼接&#xff1f; 使用示例 Go 语言中的字符串只是一个只读的字节…