1. 程式人生 > 實用技巧 >Codeforces 1370D Odd-Even Subsequence(二分)

Codeforces 1370D Odd-Even Subsequence(二分)

題意:給出一個長度為n的序列a【】,求選取一個長度為k的子序列b【】,使得val=min(max(b【i】(i%2==1)),b【i】(i%2==0)))的值最小,輸出最小的val。n<2e5

題解:顯然val必然是a【i】,val是取了一個min,不滿足單調性無法二分,但是可以發現,令va=max(b【i=odd】),vb=max(b【i=even】),無論va和vb的大小,最小的即是val,可以嘗試對va和vb進行二分,va和vb滿足單調性,最小的滿足check()的值就是ans。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define
fre freopen("C:\\in.txt", "r", stdin) #define _for(i,a,b) for(int i=a; i< b; i++) #define _rep(i,a,b) for(int i=a; i<=b; i++) #define lowbit(a) ((a)&-(a)) #define inf 0x3f3f3f3f #define endl "\n" using namespace std; typedef long long ll; template <class T> void read(T &x) {
char c; bool op=0; while(c=getchar(), c<'0'||c>'9') if(c=='-') op=1; x=c-'0'; while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0'; if(op) x=-x; } const int maxn=2e5+5; int T, n, k, a[maxn], idx[maxn]; bool cmp(int x, int y){ return a[x]<a[y]; } int check(int x) {
int cnt=0; _rep(i, 1, n) if(cnt&1){ if(a[i]<=x) cnt++; }else cnt++; if(cnt>=k) return true; cnt=0; _rep(i, 1, n) if(!(cnt&1)){ if(a[i]<=x) cnt++; }else cnt++; if(cnt>=k) return true; return false; } int main() { //read(T); T=1; while(T--) { read(n), read(k); _rep(i, 1, n) read(a[i]); _rep(i, 1, n) idx[i]=i; sort(idx+1, idx+1+n, cmp); //_rep(i, 1, n) cout<<idx[i]<<" \n"[i==n]; int l=1, r=n; while(l<=r){ int mid=(l+r)>>1; if(check(a[idx[mid]])) r=mid-1; else l=mid+1; } printf("%d\n", a[idx[l]]); } return 0; }