CF1185C2 题解

洛谷传送门 & CF 传送门

思路

第一反应是准备一个大根堆 qq 和一个记录当前堆里数总和的变量 nownow,然后在输入的同时先把总和 nownow 加上 aia_i,然后把 qq 里的数弹到 nowmnow\le m 为止,最后再把 aia_i 插到 qq 里去。这里注意,要先弹数再插 aia_i!!!因为规定 aia_i 自身不能弹掉!代码如下:

# include <bits/stdc++.h>
using namespace std;
int n, m, x, now, tot;
priority_queue <int> q;
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> n >> m;
	while (n --) {
		cin >> x;
		now += x;
		while (now > m && ! q.empty ())
			now -= q.top (), q.pop (), ++ tot; //tot 用于记录目前删掉的数个数
		q.push (x);
		cout << tot << ' ';
	}
	return 0;
}

然后,你会发现 WA 在了第 1313 个点。这里蒟蒻提供一组自制 Hack 数据:

3 10
5 6 5

我们来分析一下这个方法的漏洞。这个方法的错误原因就在于题目规定了 aia_i 自身不能弹掉,这就导致了先前弹掉的数在后面不一定也要弹,即可能出现之前弹掉的数甚至比 aia_i 自身还小的情况。这对处理 aia_i 自身没任何问题,但是对后续就有问题了。不明白的读者可以手动模拟上面的 Hack 数据。

于是,我们要弥补这个漏洞的突破口就在于我们只需要把操作回退到加 xx 之前就行,别的数弹不弹掉已经无所谓了。至于回滚操作,我们可以准备一个小根堆 poperpoper 用于存储已经被弹掉了的数。这时候,我们就不用急着将 aia_i 插进 qq 里,因为 aia_i 插不插对输出答案是没有影响的。

poperpoper 为空或 poperpoper 的堆顶(也就是弹出的数中最小的那个数)比 aia_i 还大时,这是我们不用回滚,我们也只能乖乖把 aia_i 插进 qq 里。否则,我们要在输出完毕后回滚一次操作,即我们把先前加上 aia_inownow 再减去 aia_i 还,这时我们的 nownow 肯定远远小于 mm 了,我们要把 nownow 加到不能再加(再加就要 now>mnow>m 了)为止。我们要尽量把小的换回去,这样换回去的个数才能尽量多,这也就是我们选择使用小根堆的原因。

代码

# include <bits/stdc++.h>
using namespace std;
int n, m, x, now, tot;
priority_queue <int> q;
priority_queue <int, vector <int>, greater <int>> poper;
int main () {
	ios::sync_with_stdio (0);
	cin.tie (0);
	cout.tie (0);
	cin >> n >> m;
	while (n --) {
		cin >> x;
		now += x;
		while (! q.empty () && now > m)
			now -= q.top (), poper.push (q.top ()), q.pop (), ++ tot;
		cout << tot << ' ';
		if (poper.empty () || poper.top () >= x) { //不用换
			q.push (x);
			continue;
		}
		now -= x;
		++ tot; //x 也是个数啊,所以要把删掉的数 +1
		while (! poper.empty () && now + poper.top () <= m)
			now += poper.top (), q.push (poper.top ()), poper.pop (), -- tot;
		poper.push (x);
	}
	return 0;
}
posted @   sz_jinzikai  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示