玄学求条
查看原帖
玄学求条
188970
Twiter_ln楼主2024/8/15 18:50

思路:二分答案,转化为 01 串;对于连续的0,找到满足的最大max操作次数。与m比较判断。

评测鸡路

#include<bits/stdc++.h>

using namespace std;
const int N = 1e6 + 37;

int n, m, a[N];
int l = 1, r, mid;
map <int, int> mp;

bool check(int d) {
//	cerr << "D: " << d << '\n';
	int ll = 0, rr = 0, duan = 1;
	int maxlen = 0, times = 0;
	for(int i = 1; i <= n + 1; ++ i) {
		if(a[i] >= d) {
			duan = 1;
			continue;
		}
		if(duan) {
			ll = i;
			duan = 0;
		}
		else rr = i;
		
      // 如果该串靠边,则每次-1,否则-2
		if(ll == 1 || rr == n) times = max(times, rr - ll + 1);
		else times = max(times, (rr - ll + 2) / 2);
	}
//	cerr << "Lr: " << ll << ' ' << rr << '\n';
//	cerr << "Maxlen: " << maxlen << '\n';
//	cerr << "Times: " << times << '\n';
	if(m >= times) return true;
	else return false;
}

int main() {
	
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++ i) {
		scanf("%d", &a[i]);
		r = max(r, a[i]);
		mp[a[i]] = i;
	}
	a[n + 1] = 1;
	
	while(l < r) {
		mid = (l + r + 1) >> 1;
//		cerr << l << ' ' << mid << ' ' << r << '\n';
		if(check(mid)) l = mid;
		else r = mid - 1;
//		putchar('\n');
	}
	if(mp[l]) printf("%d\n", l);
	else { // 避免二分到一个不存在的答案,向下取
		int maxx = 0;
		for(int i = 1; i <= n; ++ i) {
			if(a[i] < l) maxx = max(maxx, l);
		}
		printf("%d\n", maxx);
	}
	return 0;
}
/*

4 0
3 2 3 1
: 1

4 2
1 2 3 3
: 3

10 1
4 5 7 6 6 9 11 8 10 6
: 

*/
2024/8/15 18:50
加载中...