Problem:
a 数组中大于等于 k 个元素的区间中取出第 k 大放入到 b 数组中,最后求 b 数组的第 m 大
Solution:
二分答案ans(b 数组中的第 m 大),然后用ans去检验a数组中是否存在大于等于 m 个区间满足第 k 大大于等于ans,存在则表示ans还可以更大一点,不存在则表示ans需要小一点 。
最终跳出二分后,所得出的数一定是存在a数组中的
#include<bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define _for(i,s,t) for(int i=s;i<t;i++) #define _rof(i,s,t) for(int i=s;i>t;i--) #define rep(i,s,t) for(int i=s;i<=t;i++) #define per(i,s,t) for(int i=s;i>=t;i--) #define Ri(x) scanf("%d",&x) #define Rii(x,y) scanf("%d%d",&x,&y) #define INF 0x3f3f3f3f using namespace std; template<class T>inline void read(T &res) { char c;T flag=1; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; } typedef long long ll; const int maxn = 1e5 + 10; ll a[maxn]; ll T,N,K,M; bool check(int mid){ int l = 1,r = 0,num = 0; ll res = 0; while(l <= N){ while(r <= N && num < K){ if(a[++r] >= mid) num ++; } if(num == K){ res += (N - r + 1); } if(a[l] >= mid) num --; l ++; } return res >= M; } int main(){ IOS; cin>>T; while(T--){ cin>>N>>K>>M; rep(i,1,N){ cin>>a[i]; } ll l = 1,r = 1e9,ans; while(l <= r){ ll mid = (l + r) >> 1; if(check(mid)){ l = mid + 1; ans = mid; }else{ r = mid - 1; } } cout<<ans<<endl; } return 0; } /** Problem: a 数组中大于等于 k 个元素的区间中取出第 k 大放入到 b 数组中,最后求 b 数组的第 m 大 Solution: 二分答案ans(b 数组中的第 m 大),然后用ans去检验a数组中是否存在大于等于 m 个区间满足第 k 大大于等于ans,存在则表示ans还可以更大一点,不存在则表示ans需要小一点 。 最终跳出二分后,所得出的数一定是存在a数组中的 */