QOJ #5076. Prof. Pang and Ants 题解

news/2025/9/24 9:37:42/文章来源:https://www.cnblogs.com/Scarab/p/19108554

Description

在庞教授的大房子边上,有一群包含 \(m\) 只蚂蚁的蚁群,居住在有 \(n\) 个洞口的洞穴里。 它们会外出寻找食物。食物在庞教授的大冰箱里,蚂蚁们试图从里面偷出食物来。

特别的, 一只蚂蚁需要 \(1\) 秒从任何洞口离开,并同样需要 \(1\) 秒从任何洞口进入洞穴。不同的洞口有不同的位置,对一个洞口来说,它与冰箱的距离以 \(a_i\) 表示,同样的,一只蚂蚁从冰箱偷出食物再到第 \(i\) 个洞口的时间也是 \(a_i\) 秒。由于蚂蚁们技术高超,从冰箱拿出食物不会消耗它们任何时间。

每只蚂蚁都必须且只能从冰箱偷一次食物。蚂蚁可以任意选择一个洞口出发并进入任何一个洞口,两个洞口可以不同。一个洞口在 \(1\) 秒内只能有一只蚂蚁进出。因为这个原因,有些蚂蚁在偷完食物后需要等待一段时间才能进入洞口。

所以,你作为庞教授的好朋友, 需要计算出蚂蚁们偷出食物的最短时间。时间的定义为至少存在一只蚂蚁在洞穴外的时间总长,正在进出洞口的蚂蚁不被看作在洞穴里。

\(\sum n\leq 5\times 10^5,m\leq 10^{14}\)

Solution

二分答案 \(T\)

首先对于洞口 \(i\),第 \(k\) 个出洞的蚂蚁到冰箱的时间是 \(a_i+k\),第 \(k\) 个入洞的蚂蚁从冰箱出发的时间是 \(a_i+T-k+1\)。两只蚂蚁能够匹配当且仅当第一只蚂蚁到冰箱的时间不超过第二只蚂蚁从冰箱出发的时间。

一定满足出洞的占用的是一段时间上的前缀,入洞的占用的是一段后缀,否则调整之后显然更优。

考虑把入洞的过程也看成从洞里走向冰箱,问题变为需要对每个洞选择两个前缀,\(\{a_i+1,a_i+2,\ldots,a_i+s_i\}\)\(\{a_i+1,a_i+2,\ldots,a_i+t_i\}\),分别表示入洞的蚂蚁到冰箱的时间以及出洞的蚂蚁到冰箱的时间,需要满足 \(s_i+t_i\leq T\)

现在对所有的前缀和后缀分别合并的结果需要找到一个大小为 \(m\) 的匹配,使得每个匹配的两个数加起来不超过 \(T\)

感性理解一下,前缀和后缀的集合一定尽量相同,否则看起来不太平衡?所以每个洞口一定满足入洞的占用不超过前一半,出洞的占用不超过后一半,这样就基本保证了不交这个限制。


后面的过程还是换回最开始的判定。

对于 \(T\) 是偶数的情况,把所有洞口 \(i\) 的前缀 \([a_i+1,a_i+T/2+1]\) 和后缀 \([T/2,T-a_i-1]\) 分别归并起来,从小到大贪心判断匹配数是否大于等于 \(m\) 即可。

如果 \(T\) 是奇数,则每个洞口在正中间的时间会有一点小细节。注意到类型相同的正中间时刻之间是无法匹配的,考虑把正中间的时刻拆成可以进出各 \(0.5\) 只蚂蚁,根据对称性,拆除来的两个小蚂蚁最终匹配的结果一定(?)也对称,可以看成一只中间的蚂蚁匹配两个对称蚂蚁中的一个。

时间复杂度:\(O(n\log n+n\log m)\)

Code

#include <bits/stdc++.h>#define int int64_tconst int kMaxN = 1e5 + 5;int n, m;
int a[kMaxN];template<class T>
void merge(std::vector<T> &v1, std::vector<T> &v2) {std::vector<T> ret;for (int i = 0, j = 0; i < v1.size() || j < v2.size();) {if (i < v1.size() && (j == v2.size() || v1[i] < v2[j])) ret.emplace_back(v1[i++]);else ret.emplace_back(v2[j++]);}v1.swap(ret);
}bool check(int t) {std::vector<std::tuple<int, int, int>> vec;if (t % 2 == 0) {std::vector<std::tuple<int, int, int>> vv[4];for (int i = 1; i <= n; ++i) vv[0].emplace_back(a[i] + 1, 0, 2);for (int i = 1; i <= n; ++i) vv[1].emplace_back(a[i] + t / 2 + 1, 0, -2);for (int i = n; i; --i) vv[2].emplace_back(t / 2 - a[i], 1, 2);for (int i = n; i; --i) vv[3].emplace_back(t - a[i], 1, -2);for (int i = 0; i < 4; ++i) merge(vec, vv[i]);} else {std::vector<std::tuple<int, int, int>> vv[6];for (int i = 1; i <= n; ++i) vv[0].emplace_back(a[i] + 1, 0, 2);for (int i = 1; i <= n; ++i) vv[1].emplace_back(a[i] + t / 2 + 1, 0, -1);for (int i = 1; i <= n; ++i) vv[2].emplace_back(a[i] + t / 2 + 2, 0, -1);for (int i = n; i; --i) vv[3].emplace_back(t / 2 - a[i], 1, 1);for (int i = n; i; --i) vv[4].emplace_back(t / 2 - a[i] + 1, 1, 1);for (int i = n; i; --i) vv[5].emplace_back(t - a[i], 1, -2);for (int i = 0; i < 6; ++i) merge(vec, vv[i]);}int cnt = 0, las = 0, now[2] = {0};for (int i = 0; i + 1 < (int)vec.size(); ++i) {if (i + 1 < (int)vec.size() && std::get<0>(vec[i]) == std::get<0>(vec[i + 1])) continue;int len = std::get<0>(vec[i + 1]) - std::get<0>(vec[i]);for (int j = i; ~j; --j) {if (std::get<0>(vec[j]) != std::get<0>(vec[i])) break;now[std::get<1>(vec[j])] += std::get<2>(vec[j]);}if (now[0] >= now[1]) {cnt += now[1] * len, las += (now[0] - now[1]) * len;} else {cnt += now[0] * len;int c1 = (now[1] - now[0]) * len;cnt += std::min(c1, las), las -= std::min(c1, las);}}return cnt >= 2 * m;
}void dickdreamer() {std::cin >> n >> m;for (int i = 1; i <= n; ++i) std::cin >> a[i];std::sort(a + 1, a + 1 + n);int L = 0, R = 2e14, res = 2e14;while (L + 1 < R) {int mid = (L + R) >> 1;if (check(mid)) R = res = mid;else L = mid;}std::cout << res << '\n';
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;std::cin >> T;while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}

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

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

相关文章

微信小程序(uniapp)PDF预览完整实现方案

微信小程序(uniapp)PDF预览完整实现方案Posted on 2025-09-24 09:36 且行且思 阅读(0) 评论(0) 收藏 举报在微信小程序开发中,PDF文件预览是常见的业务需求。本文将提供一套基于uniapp的完整解决方案,涵盖从后…

发现5个宝藏文件摆渡系统 2025年企业首选的摆渡方案是这个!

文件摆渡系统作为解决网络隔离后业务交互的重要工具,其作用和价值不言而喻。不过对于企业的价值究竟是正面的,还是负面的,这就要看用的什么文件摆渡系统了。本文中我们就介绍5种文件摆渡系统,我们来看看首选的摆渡…

如何打开谷歌网站网站备案网站

文章目录 一、文档转换器 & 文本拆分器文本拆分器 二、开始使用文本拆分器三、按字符进行拆分四、代码分割 (Split code)1、PythonTextSplitter2、JS3、Markdown4、Latex5、HTML6、Solidity 五、MarkdownHeaderTextSplitter1、动机2、Use case 六、递归按字符分割七、按tok…

基金网站建设网站建设运营知识

移动应用程序开发的增长速度比以往任何时候都快。几乎每个企业都需要移动应用程序来保持市场竞争力。由于像 React Native 这样的跨平台移动应用程序开发框架允许公司使用单一源代码和单一编程语言构建 iOS 和 Android 应用程序&#xff0c; Flutter是 Google 支持的另一个热门…

BilldDesk:基于Vue3+WebRTC+Nodejs+Electron的开源远程桌面控制 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

css-轮播图效果

<!DOCTYPE html> <html lang="zh-EN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"&g…

aspnetcore使用websocket实时更新商品信息

aspnetcore使用websocket实时更新商品信息先演示一下效果,再展示代码逻辑。中间几次调用过程省略。。。 暂时只用到了下面四个项目1.产品展示页面中第一次通过接口去获取数据库的列表数据/// <summary> /// 获取…

漏洞挖掘实战:如何定制化模糊测试技术

本文深入探讨如何定制化模糊测试工具syzkaller来挖掘Linux内核漏洞。从基础架构解析到实战技巧,涵盖权限设置、网络接口测试、结果筛选机制以及七种独特漏洞发现方法,适合安全研究人员参考。适配模糊测试以挖掘漏洞 …

css-遮罩层效果

<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">&…

nuxt3中使用pdfjs-dist实现pdf转换canvas实现浏览

获取 pdfjsLib.GlobalWorkerOptions.workerSrc 的cdn链接地址https://cdnjs.com/libraries/pdf.js 代码 https://files.cnblogs.com/files/li-sir/cspdf.zip?t=1758676920&download=true

查看linux部署网站的TLS版本号

curl https://域名 -version无可奈何花落去,似曾相识燕归来

【SpringBoot- Spring】学习

Spring官方文档翻译(1~6章 转载至 http://blog.csdn.net/tangtong1/article/details/51326887 Spring官方文档、参考中文文档 一、Spring框架概述 Spring框架是一个轻量级的解决方案,可以一站式地构建企业级应用。Sp…

css-更改鼠标样式

<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">&…

css-浮动围绕文字效果

<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">&…

浙江省建设厅网站地址网页游戏排行榜 2020

文章目录 前言不使用对象池使用官方内置对象池应用 自制对象池总结源码参考完结 前言 对象池&#xff08;Object Pool&#xff09;是一种软件设计模式&#xff0c;用于管理和重用已创建的对象。在对象池中&#xff0c;一组预先创建的对象被维护在一个池中&#xff0c;并在需要时…

怎样建设电影网站找人做一个小网站需要多少钱

当下&#xff0c;新媒体矩阵营销已成为众多企业的营销选择之一&#xff0c;各企业可以通过新媒体矩阵实现扩大品牌声量、维持用户关系、提高销售业绩等不同的目的。 而不同目的的矩阵&#xff0c;它的内容运营模式会稍有差别&#xff0c;评价体系也会大不相同。 企业在运营某类…

网站建设与实训怎么给网站引流

在大型语言模型&#xff08;LLM&#xff09;的世界中&#xff0c;有两个强大的框架用于部署和服务LLM&#xff1a;vLLM 和 Text Generation Interface (TGI)。这两个框架都有各自的优势&#xff0c;适用于不同的使用场景。在这篇博客中&#xff0c;我们将对这两个框架进行详细的…

连江网站建设c 语言网站建设

Zotero有着强大的文献管理功能&#xff0c;之前也对其进行过简要介绍&#xff08;Zotero——一款文献管理工具&#xff09;&#xff0c;而安装一些必要的插件则可以使其如虎添翼&#xff0c;今天一起来探索一下一些实用的插件吧&#xff01;&#xff08;排名不分先后&#xff0…

怎样做访问外国网站才能不卡iis部署网站 错误400

一、axios Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 二、配置代理 1. 方法一 在…

按照DDD的方式写的一个.net有关Web项目框架

按照DDD的方式写的一个.net有关Web项目框架理想很丰满,现实往往很残酷。 一种按照ddd的方式,根据业务来把自己需要的模块一个一个写出来,再按照模块把需要的接口一个一个的写出来,堆砌一些中间件,以及解耦的comma…