K-th Number
题目大意
给一个数组a包含n(1e5)个数,给出 k,m。
构造数组b:在a的所有大于等于k的区间中选出第k大的数加到b里面。
问b数组中第m大的数。
题解
我好菜。。想不到二分,感觉最近脑子不动了,很fan
二分答案,
然后怎么check?
b里的数肯定有m个大于等于mid的数。
怎么看有没有呢? 可以用m当作check的条件改变二分的l,r。
统计区间里第k大大于等于mid的数量,怎么统计?尺取,
就相当于取k个大于等于mid的数 有多少个区间,
尺取可以枚举区间的左侧,然后尺取 取到右侧,然后统计就可以,,
代码
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <set>
#include <queue>
#include <string>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
int a[maxn];
int n,k;
ll m;
bool pd(int x)
{
ll s =0 ;
int sum = 0, l= 1, r = 1;
while(1)
{
while(r <= n && sum < k)
{
if(a[r] >= x)
sum ++ ;
r ++ ;
}
if(sum < k)
break;
s += n - r + 2;
if(a[l] >= x) sum -- ;
l ++ ;
}
return s >= m;
}
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 = 0,r = 1e9;
while(l < r)
{
int mid = l + r + 1 >> 1;
if(pd(mid))
l = mid;
else
r = mid - 1;
}
printf("%d\n",l);
}
}
我菜了。。