Solution - Luogu P11393 [JOI Open 2019] 送金

news/2024/12/20 20:36:45/文章来源:https://www.cnblogs.com/rizynvu/p/18619899

下标默认是在 \(\bmod\ n\) 意义下的。

考虑到如果 \(a_i > b_i\) 那么不可能只操作 \(a_{i - 1}\) 使得 \(a_i\) 合法,因为这只增不减。
于是这说明当 \(a_i > b_i\) 时一定会操作 \(a_i\) 使得 \(a_i\le b_i\)

但是同时如果 \(b_i - a_i\) 太大了,\(a_{i - 1}\) 就不一定能操作完了。
于是贪心的,当 \(a_i > b_i\) 时,让调整后的 \(b_i - a_i\) 尽量小,就能给后面的步骤留出更多的调整空间。
所以若 \(a_i\bmod 2 = b_i\bmod 2\),则操作 \(a_i\) 使得 \(a_i\leftarrow b_i\);否则操作 \(a_i\) 使得 \(a_i\leftarrow b_i - 1 + 2[b_i = 0]\)(当 \(b_i = 0\) 时,因为需要满足时刻 \(a_i\ge 0\),只能使 \(a_i = 1\))。

根据这个贪心的思想,每一步都在使得 \(a_i\) 能够更接近 \(b_i\)
所以一直这样操作下去直到无法操作,如果满足 \(\forall i\in [1, n], a_i = b_i\) 则合法,否则不合法。
(可以手玩一下不合法的局面,能发现此时操作任意一个 \(a_i\)\(a_i\) 至少也会 \(-1\),只会变小,之后就肯定不可能变大成 \(b_i\) 了。)

那么接下来考虑快速模拟这个过程了。
首先可以先模拟一圈(\(1\sim n\) 做一次贪心),那么能发现此时的 \(a_i\) 是比较有性质的。

具体来说,\(\forall i\in [2, n]\),要么 \(a_i = 1\)\(b_i = 0\),要么 \(a_i\le b_i\)
这是因为 \(2\sim n\) 按顺序调整后 \(i - 1\) 没有再次进行操作,所以依然保持原样。
且此时 \(a_1\le 2V\),舍弃掉 \(\bmod\ 2\) 后的余数的损失,考虑距离 \(1\)\(d\) 那么给到 \(a_1\) 的贡献至多为 \(\frac{V}{2^d}\),那么有 \(\sum\limits_{i = 0}^{n - 1} \frac{V}{2^i}\le 2V\)

那么操作 \(1\) 后至多 \(a_2\) 得到 \(\lfloor\frac{a_1}{2}\rfloor = V\) 的增量。
再往后,令当前在位置 \(i\)\(i - 1\)\(a_i\) 的增量为 \(x\),考虑此时满足要么 \(a_i = 1\)\(b_i = 0\),要么 \(a_i\le b_i\),所以 \(i\) 给到 \(i + 1\) 的增量肯定不会超过 \(\lfloor\frac{x + 1}{2}\rfloor\)

那么可以知道的是,在 \(\mathcal{O}(\log V)\)(精确值应当是 \(31\))轮后,增量 \(x\) 就会变为 \(1\)

此时考虑若增量为 \(1\)\(a_i = 1, b_i = 0\),或者 \(a_i = b_i\not = 0\) 时带给下一轮的增量依然为 \(1\)
首先考虑 \(a_i = 1, b_i = 0\) 这种情况,那么在得到增量并进行操作后,\(a_i = b_i = 0\),等再转过来时因为能产生的增量 \(\le 1\),那么这个位置已经产生不了增量了,于是最多转 \(n\) 次就会结束。
然后考虑 \(a_i = b_i\not = 0\) 这种情况,那么在得到增量并进行操作后,\(a_i = b_i - 1\),一样的等再转过来时这个位置一定产生不了增量,于是最多转 \(n\) 次就会结束。

综上,能够知道的是在增量 \(x = 1\) 后最多转一圈,也就是继续往后模拟 \(n\) 次后一定会终止。

于是可以知道,最多 \(2n + \mathcal{O}(\log V)\) 次模拟后就不会产生增量,\(a_i\) 就不会发生改变了。

直接模拟即可,时间复杂度 \(\mathcal{O}(n + \log V)\)

#include<bits/stdc++.h>
constexpr int maxn = 1e6 + 10;
int a[maxn], b[maxn];
int main() {int n;scanf("%d", &n);for (int i = 0; i < n; i++) scanf("%d%d", &a[i], &b[i]);for (int T = 0; T < n + 33 + n; T++) {int i = T % n, j = (i + 1) % n;if (a[i] < b[i]) continue;if (! b[i]) {a[j] += a[i] / 2, a[i] %= 2;} else {int d = (a[i] - b[i] + 1) / 2;a[j] += d, a[i] -= d * 2;}}for (int i = 0; i < n; i++) {if (a[i] != b[i]) {return puts("No"), 0;}}return puts("Yes"), 0;
}

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

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

相关文章

20222418 2024-2025-1《网络与系统攻防技术》实验八实验报告

1.实验内容 (1)Web前端HTML 能正常安装、启停Apache。理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTML。 (2)Web前端javascipt 理解JavaScript的基本功能,理解DOM。 在(1)的基础上,编写JavaScript验证用户名、密码的规则。在用户点击登陆按钮后回显“欢迎+…

Java 基础概览

1. Java 语言概述 1.1 Java 简史 Java是一种高级程序设计语言,由SUN(Stanford University Network,斯坦福大学网络公司)公司于1995年推出,James Gosling设计Java语言,并开发了Java编译器和Java虚拟机,因此也被人尊称为“Java 之父”。SUN公司在2009年被Oracle(甲骨文)…

Linux学习笔记(一) Linux目录结构

下图显示的为Linux中的目录结构:/bin[常用](/usr/bin、/usr/local/bin) 是Binary(二进制)的缩写,这个目录存放着经常使用的命令。 /sbin(/usr/sbin、/usr/local/sbin) s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。 /home[常用] 存放普通用户的家目…

数据库审计与监控

title: 数据库审计与监控 date: 2024/12/20 updated: 2024/12/20 author: cmdragon excerpt: 数据库审计与监控是确保数据库安全性和性能的关键环节。通过实施有效的审计策略,可以追踪用户活动,监控数据访问与修改,从而及时发现潜在的安全威胁和性能瓶颈。探讨数据库审计的基…

Java实现单词的翻译(详解爬虫操作)

JAVA通过Crawler实现英语单词的翻译首先声明一点,这种方法仅限于低频次的交互来获取翻译信息,一旦一秒内大量的请求会被重定向,那就直接不能用了 如果希望可以批量查询英语单词翻译,可以查看我的下一篇博客。接着我们上一讲Java如何用HaspMap统计次数并排序详解 - ivanlee7…

实用工具:Calibre 7.22最新版 一款Window电子书管理工具和阅读器便携版

📢提示:文章排版原因,链接放在文章结尾👇👇,往下翻就行 📢提示:文章排版原因,链接放在文章结尾👇👇,往下翻就行 前言 初识Calibre 最近有几本epub格式的电子书要看发现电脑上没有可以打开的软件,所以最近找到了这个软件。功能 功能亮点电子书管理:Calib…

VS2022 C++QT 中文乱码 设置UTF-8编码

说明 所有内容来源于网络 通过插件调整源文件编码FileEncoding:查看编码 Force UTF-8:用于保存为UTF-8 C++项目设置为utf-8 项目-属性-配置属性-C/C++-命令行-其它选项 中 增加/utf-8、

雷池 WAF 配置了多条人机验证规则,命中规则是怎样的?

优先级说明 频率限制(1 小时) > 自定义规则(1 小时) > 站点 BOT 防护(自定义时长) 配置人机验证的地方 【防护配置-频率限制】限制结果选择【人机验证】【防护配置-自定义规则】规则类型选择【人机验证】【防护站点-站点管理】的【BOT 防护】中开启【人机验证】命中…

如何在C#.NET中使用LINX(arduino的LabView库)

思路:使用LabView的导出为.NET互操作程序集,导出COM给.NET调用在LabView安装HubMaker插件,将预编译固件刷入Arduino设备中。这不是本文的重点,省略 根据需要,编写VI。注意:必须在此处使用全局变量或者其它方法避免LinxResource簇在C#中出现,否则在程序运行时有概率出现堆…

C#.Net NModbus库 简单代码案例(非Nmodbus4库)

在NuGet管理器中搜索NModbus。注意,如果需要使用串口通信需要同时选中相关包

EyeSoothe荣登中国区“健康健美”类第32名! ✨

眼睛疲劳、视力变化、色盲检测、虚拟眼镜试戴……这些问题,EyeSoothe都能帮你解决!作为一款全能眼健康应用,EyeSoothe集成了多个强大功能,旨在帮助你更好地保护视力,缓解眼部疲劳,随时关注眼健康。📱💡 https://apps.apple.com/app/eyesoothe/id6478070048 为什么选择…

腾讯云 AI 代码助手:代码诊断应用实践

代码诊断是指通过分析和检查源代码,发现并定位其中的错误、缺陷或不规范之处。传统的代码诊断方法主要依赖于人工审查和简单的静态分析工具,结合流水线的自动化能力并且结合质量门禁建立不同的质量阈值关卡。基于 AI 赋能代码诊断是在传统的能力基础上在次进行质量左移,通过…