题意: 从长度为
的序列
中选
个数组成序列
,求出
题解: 二分答案。我们不断缩小二分的答案
。
由于是求奇数序列和偶数序列的最大值中的最小值,可以分别求这两者的最大值,若两个最大值都不符合条件,那么说明答案至少为
,否则答案至多为
。
由于是求两者的最小值,最后二分的答案要么是正好奇数序列和偶数序列可以求得的最小值,即此时两者相同。或者只是其中一方的最小值。
可能的疑惑: 如果奇数序列或偶数序列中还可求出比当前答案还小的值,则会将左端点加
继续
,直到答案是
。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n, k;
int q[N];
bool check(int x) {
for(int i = 1, cnt = 0; i <= n; i++) { //even sequence
//fetch q[i] when cnt is odd, so q[i] as b[2k] (k>=1)
if((cnt % 2 && q[i] <= x) || (cnt % 2 == 0)) cnt++;
if(cnt >= k) return true;
}
for(int i = 1, cnt = 0; i <= n; i++) { // odd sequence
//fetch q[i] when cnt is even, so q[i] as b[2k+1] (k>=0)
if((cnt % 2 == 0 && q[i] <= x) || cnt % 2) cnt++;
if(cnt >= k) return true;
}
return false;
}
int b_s(int l = 1, int r = 1000000000) {
while(l < r) {
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
void solve() {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++) scanf("%d", &q[i]);
printf("%d\n", b_s());
}
int main()
{
int T = 1;
//scanf("%d", &T);
while(T--) {
solve();
}
return 0;
}