【题解】 Codeforces 1852A Ntarsis' Set
题目传送门:Codeforces 1852A Ntarsis' Set
题意
给定一个集合,里面初始有
分析
-
思考如果
在这天没有被删掉,那么哪些被删掉的位置会对它产生什么样的影响解答:如果
,那么他会移动到 的位置 -
带着这个发现,去反向模拟
题解
首先我们运用逆向思维,不去直接模拟删除元素,而是模拟插入
如何模拟这个过程呢?我们可以简化这个思路,第一个
- 如果第一个元素是
,那么第一天就会有贡献 - 如果第二个元素是
,那么第二天会有贡献 - 如果第二个元素是
,那么第四天会有贡献 - 推广至第
个元素,设当前 的位置为 ,那么还需要(a[inc] - ans + inc - 1) / inc
天才能有贡献
AC代码
#include <bits/stdc++.h> using namespace std; int n, k, a[200010]; void solve() { cin >> n >> k; for (int i = 0; i < n; i++) { cin >> a[i]; a[i] -= i; } if (a[0] != 1) { cout << 1 << "\n"; return; } a[n] = 2e9; //start at position 1, and find what number moves to its position long long ans = 1; int inc = 1; //how many zeroes to insert while (inc < n) { int days = (a[inc] - ans + inc - 1) / inc; // 需要多少天才能有效贡献 if (days >= k){ // k不足,计算之前的元素可以贡献的有效的插入的0 ans += k * inc; k = 0; break; } ans += days * inc; // k充足,计算总贡献 k -= days; // 这里 - days,表示 花费的轮数 // 小于的元素,表示已经被前面的其他元素覆盖,没起作用 while (a[inc] <= ans) inc++; } ans += 1ll * k * n; // 剩下的k轮,每次可以插入n个0,走n步 cout << ans << "\n"; } int main() { ios::sync_with_stdio(0); cin.tie(nullptr); int t; cin >> t; while (t--) solve(); }
本文作者:KeanShi
本文链接:https://www.cnblogs.com/keanshi/p/17581045.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步