题意:给你数列A,对于A的每一个区间,求第K大,插入到数列B中,最后再求数列B的第M大!
思路:二分答案,尺取。如果到i找到了k个大于等于x的数,再向i的后面找,即在区间[1,i+1],[1,i+2],[1,i+3]…[i,n],所以这些区间都可以找到第K大的数大于等于x,这些数都要入数列B,此时尺取的r就不用向后找了,直接相加就可以,l要向前挪,要是挪的数小于x,继续挪,不然num–,因为此时j对应的数挪走,x就不是第k大数了。
要是ans<m,x大了,r=mid-1;
else l=mid+1;
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,k,M;
ll a[100005];
bool judge(ll x){
ll ans=0;
ll num=0;
int j=1;
for(int i=1;i<=n;i++){
if(a[i]>=x)num++;
if(num==k){
ans+=n-i+1;
while(a[j]<x){
ans+=n-i+1;
j++;
}
num--;
j++;
}
}
if(ans>=M)return true;
else return false;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%lld%lld%lld",&n,&k,&M);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
ll l=1,r=1000000000;
ll m;
while(l<=r){
m=(l+r)>>1;
if(judge(m)){
l=m+1;
}
else r=m-1;
}
printf("%d\n",l-1);
}
return 0;
}