专栏文章

题解:CF2093E Min Max MEX

CF2093E题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mino1em4
此快照首次捕获于
2025/12/02 05:33
3 个月前
此快照最后确认于
2025/12/02 05:33
3 个月前
查看原文
一看到“最小值最大”,二分便是显而易见的了。
二分答案,然后就来写判断函数里的东西。
传进来了一个数xx,接下来就是验证xx的可行性。
考虑用ss记录一共分了几个集合,ansans记录当前集合的 MEXMEX 。 之后,如果ans=xans = x,就新开一个集合,再把之前的标记删掉。最后,如果xsx \le s,则返回真,否则为假。

code

CPP
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int T, n, k, a[N], mx;
bool mp[N];
vector<int> v;
bool check(int x) {
	for(auto i : v) mp[i] = 0;
	v.clear();
	int s = 0, ans = 0;
	for(int i = 1; i <= n; i++) {
		if(a[i] <= 2e5) {
			v.push_back(a[i]);
			mp[ a[i] ] = 1;
		}
		while(mp[ans]) ans ++;
		if(ans >= x) {
			s ++;
			ans = 0;
			for(auto i : v) mp[i] = 0;
			v.clear();
		}
	}
	return (s >= k);
}
int main() {
	scanf("%d", &T);
	while(T --) {
		mx = 0;
		scanf("%d%d", &n, &k);
		for(int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
			mx = max(mx, a[i]);
		}
		int l = 0, r = min(mx + 1, 200000), mid;
		while(l < r) {
//			cout << l <<' ' << r <<' ' << mid <<'\n';
			mid = (l + r + 1) / 2;
			if(check(mid)) l = mid;
			else r = mid - 1;
		}
		printf("%d\n", l);
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...