题意:有T组数据。 每组数据给定长度为 N的数组 A,对所有长度大于等于 k 的连续子段,取出其第 k 大放入数组 B 中。求数组 B 的第 M 大。
思路:二分答案x检查可行性,x是B数组的第M大所以B数组就有M个大于等于x的数,求有多少个大于X的数就是求有多少个区间的第K大大于X。s[i]表示从1-i大于等于X的数量利用这个求一个区间的第K大是否大于x,再通过尺取长度为K的区间即可。
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long ll;
const int N=1e5+10;
ll n,m,k,t;
int a[N];
int s[N];//1-i多少个数大于等于x
bool check(int x)
{
ll sum=0;
for(int i=1;i<=n;i++)
{
s[i]=s[i-1]+(a[i]>=x);
}
int l=1;
for(int r=k;r<=n;r++)//想想这里怎么做
{
while(s[r]-s[l-1]>=k) l++;
sum+=l-1;
}
return sum>=m;
}
int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld",&n,&k,&m);
int l=1,r=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
r=max(r,a[i]);
}
//b m个数大于等于x
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
cout<<l<<endl;
}
return 0;
}