思路:二分答案,转化为 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
:
*/