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数组中的
*/


京公网安备 11010502036488号