Alice are given an array
A[1..N]
with
N
numbers.
Now Alice want to build an array B by a parameter K as following rules:
Initially, the array B is empty. Consider each interval in array A. If the length of this interval is less than K , then ignore this interval. Otherwise, find the K -th largest number in this interval and add this number into array B .
In fact Alice doesn't care each element in the array B. She only wants to know the M -th largest element in the array B
Input
The first line is the number of test cases.
For each test case, the first line contains three positive numbers N(1≤N≤105),K(1≤K≤N),M . The second line contains N numbers Ai(1≤Ai≤109)
.
It's guaranteed that M is not greater than the length of the array B.
Output
For each test case, output a single line containing the
M
-th largest element in the array
B
.
Sample Input
Sample Output
题意:懒得说了
思路:这题最大的难点就是想到二分了,为什么可以想到二分呢,因为对于把数组里的数,我们显然可以通过二分确定位置,但是如果把b数组直接表示出来,显然是不能的,
但是分析发现,如果我们通过二分去确定位置,我们只用知道比当前数大的数有多少个,那么我们在分析可以知道,只要当某个区间的第k大的数大于等于当前二分的数,
剩下包含这个区间的区间都不用考虑了,如果小于的话只用吧终点往后移动,所以每一个数最多遍历两次,当然就是尺取了,那么怎么知道当前区间的第k大呢,一开始我都想用主席树了,但是其实不用我们只用维护当前区间大于等于x的个数就行了
ac代码:
Now Alice want to build an array B by a parameter K as following rules:
Initially, the array B is empty. Consider each interval in array A. If the length of this interval is less than K , then ignore this interval. Otherwise, find the K -th largest number in this interval and add this number into array B .
In fact Alice doesn't care each element in the array B. She only wants to know the M -th largest element in the array B
. Please help her to find this number.
For each test case, the first line contains three positive numbers N(1≤N≤105),K(1≤K≤N),M . The second line contains N numbers Ai(1≤Ai≤109)
It's guaranteed that M is not greater than the length of the array B.
2 5 3 2 2 3 1 5 4 3 3 1 5 8 2
3 2
#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int maxn = 1e5+50;
int n,k;
int a[maxn];
LL m;
int T;
int b[maxn];
int check(int x)
{
int l = 1;
int r = 1;
LL sum1 = 0;//xiaoyudengyu
LL sum2 = 0;//dayu
int nowk;
int cnt = 0;
if(a[l]>=x){
cnt++;
}
while(l<=r&&r<=n){
if(r-l+1>=k){
// cout<<"nowk: "<<nowk<<' '<<l<<' '<<r<<endl;
if(cnt>=k){
sum1+=(n-r+1);
if(a[l]>=x){
cnt--;
}
l++;
}
else{
r++;
if(r>n){
break;
}
if(a[r]>=x){
cnt++;
}
}
}
if(r-l+1<k){
r++;
if(a[r]>=x){
cnt++;
}
}
}
//cout<<x<<' '<<sum1<<endl;
if(sum1>=m){
return 1;
}
else{
return 0;
}
}
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d%lld",&n,&k,&m);
for(int i = 1;i<=n;i++){
scanf("%d",&a[i]);
b[i] = a[i];
}
// build(1,1,n);
sort(b+1,b+n+1);
int l = 0;
int r = n+1;
int mid;
while(r>l+1){
mid = (l+r)/2;
if(check(b[mid])){
l = mid;
}
else{
r = mid;
}
}
// cout<<r<<endl;
printf("%d\n",b[l]);
}
}