题意:给你数列A,对于A的每一个区间,求第K大,插入到数列B中,最后再求数列B的第M大。
解题思路:二分+尺取。对于当前答案,如果当前答案作为第K大的区间的总数大于M,则实际答案要比当前答案大,反之则小。统计答案作为第K大的区间个数用尺取,注意尺取法的细节问题。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
int N,K;
ll M;
int a[100005];
bool jg(int x){
ll ans=0;//区间个数
int num=0;//当前>x的数的个数
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("%d%d%lld",&N,&K,&M);
for(int i=1;i<=N;i++) scanf("%d",&a[i]);
int l=1,r=1e9;
int m;
while(l<r){
m=(l+r)/2;
if(jg(m))
l=m+1;
else
r=m;
}
printf("%d\n",l-1);
}
return 0;
}