题意:

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. Please help her to find this number.

输入:

The first line is the number of test cases.

For each test case, the first line contains three positive numbers N(1N105),K(1KN),M. The second line contains N numbers Ai(1Ai109).

It's guaranteed that M is not greater than the length of the array B.

输出:

For each test case, output a single line containing the M-th largest element in the array B.

 样例输入:

2

5 3 2

2 3 1 5 4

3 3 1

5 8 2

输出:

3

2

题目大意:给定一个序列A,将序列的每个区间(区间长度>=K)中第K大的数加入到B数组中,求B数组中第M大的数。

解题思路:二分第M大的值? 当值为X时,统计出第K大时>=X的区间个数。 如果区间个数大于M,那么答案肯定比X小。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e5+5;
int a[N],n,k;
LL m;
int check(int x)
{
    LL ans=0;
    int j=1,num=0;
    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++;
            }
            j++;
            num--;
        }
    }
    if(ans>=m) return true;
    return false;
}
int main()
{
    int T;
    ios::sync_with_stdio(false);
    cin>>T;
    while(T--){
        cin>>n>>k>>m;
        for(int i=1;i<=n;i++) cin>>a[i];
        int L=1,R=1000000000,ans=0;
        while(L<=R){
            int mid=(L+R)>>1;
            if(check(mid)) ans=mid,L=mid+1;
            else R=mid-1;
        }
        cout<<ans<<endl;
    }
}


01-14 22:53