K-th Number
题意:
从长度为n的区间中,找出长度大于等于k的区间的第k大值,把这些值放在B数组中,求B中第m大值
思路:
容易往树状数组和线段树那里思考,但其实是二分
设 mid
⩽
\leqslant
⩽ ans
有在B中,mid为第>=m的值,即在B中比mid大的值数量>=m,即在A的长度大于k的子区间中,比mid大的第k大的值的个数>=m个,即有>=m个子区间,每个区间中,比mid大的值的个数大于k个
所以有
for(int i=1;i<=n;i++)s[i]=s[i-1]+(a[i]>=mid);
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010;
int n,k,m;
int a[N],s[N];
bool check(int mid)
{
memset(s,0,sizeof s);
int sum=0,l=0;
for(int i=1;i<=n;i++)s[i]=s[i-1]+(a[i]>=mid);
for(int i=k;i<=n;i++)
{
while(s[i]-s[l]>=k)l++;
sum+=l;
}
return sum>=m;
}
signed main()
{
int T;
cin>>T;
while(T--)
{
scanf("%lld%lld%lld",&n,&k,&m);
int l=0,r=0;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),r=max(a[i],r);
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid))l=mid;
else r=mid-1;
}
printf("%lld\n",r);
}
}