abc249_f Ignore Operations 题解
Ignore Operations
题意
Takahashi 有一个整数
有
- 如果
,将整数 替换为 。 - 如果
,将整数 替换为 。
Takahashi 可以跳过其中至多
数据范围
思路
我们肯定不会跳过那些对答案有正面作用的操作,那其他的呢?
来看一张草图。
显然,在最后一次赋值操作以前,所有操作均可视为没有。
那么在最后一次赋值操作之后的那些操作呢?跳过第
那么,我们可以推出第一步:从后往前找,用堆来存储每次操作对答案的贡献,模拟一下上面的那种操作即可。
那问题是,处理好了最后一次赋值操作以后的所有,那前面的怎么办呢?
这也不难,令
统计答案即可。
复杂度
- 时间:
- 空间:
Code
点击查看代码
#include <iostream> #include <queue> using namespace std; using ll = long long; const int N = 2e5 + 10; struct Node { int op, t; } a[N]; int n, k; ll x, y, sum[N], ans, num; priority_queue<int> pq; // 堆维护 int main () { ios::sync_with_stdio(0), cin.tie(0); cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> a[i].op >> a[i].t; if (a[i].op == 1) { // 预处理 sum sum[i] = a[i].t; } else { sum[i] = sum[i - 1] + a[i].t; } ans = sum[i]; } for (int i = n; k && i >= 1; i--) { if (a[i].op == 2 && a[i].t < 0) { // 操作 2 pq.push(a[i].t); // 答案贡献,这里取了个反 num += a[i].t; // 贡献之和 if (pq.size() > k) { // 操作次数超过 k num -= pq.top(), pq.pop(); // 去掉答案贡献最小的 } } else if (a[i].op == 1) { // 操作 1 num += sum[i] - sum[i - 1]; if (pq.size() == k) { num -= pq.top(), pq.pop(); } k--; // 不可逆的操作 } ans = max(ans, sum[n] - num); // 计算答案最大值 } cout << ans; return 0; }
本文作者:wnsyou の blog
本文链接:https://www.cnblogs.com/wnsyou-blog/p/17323159.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步