题目:传送门
思路:二分答案x,用双指针判断 区间个数,区间满足至少有k个数>=x ,再根据个数和m的大小关系继续二分。易得,最后二分得到的 ans 一定是数组中的某一个数,否则就会继续二分。

#include<bits/stdc++.h> /* #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<cctype> #include<queue> #include<algorithm> #include<map> #include<set> */ #pragma GCC optimize(2) using namespace std; typedef long long LL; typedef pair<int,int> pii; typedef pair<double,double> pdd; const int N=1e6+5; const int M=1e4+5; const int inf=0x3f3f3f3f; const LL mod=1e9+7; const double eps=1e-9; const long double pi=acos(-1.0L); #define ls (i<<1) #define rs (i<<1|1) #define fi first #define se second #define pb push_back #define mk make_pair #define mem(a,b) memset(a,b,sizeof(a)) LL read() { LL x=0,t=1; char ch; while(!isdigit(ch=getchar())) if(ch=='-') t=-1; while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } return x*t; } int n,k,a[N]; LL m; int judge(int x) { LL res=0,sum=0; for(int l=1,r=1;l<=n;l++) { while(sum<k&&r<=n) sum+=a[r++]>=x; if(sum==k) res+=n-r+2; sum-=a[l]>=x; } return res>=m; } int main() { int T=read(); while(T--) { n=read(),k=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); int l=1,r=1e9; while(l<=r) { int mid=l+r>>1; if(judge(mid)) l=mid+1; else r=mid-1; } printf("%d ",r); } return 0; }