HDU - 6231_K-th Number

题面

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.

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.

题意

  • 找出区间长度大于k的所有子区间的第k大,并将他们存入B数组里,输出B数组里的第m大

题解

  • 首先我们对于一个数x,如果以他为第k大的区间数和大于x的数作为第k大的区间数的总和大于m,那么答案肯定是比x还要大的,相反,如果总和小于m,那么答案肯定要更小,这样就存在二分性,我们可以二分求答案,难点是我们要怎么去算出上述的区间总和,其实很简单,我们可以用尺取法,首先考虑一下如果我们找到前缀刚好有k个大于等于x的,那么后面的所有数都可以代表一个满足区间,因为加了后面的数,区间肯定存在第k大,而且第k大等于x或者大于x,这样我们通过维护这个刚好第k大,就可以找出所有满足区间
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const int maxn = 1e5+9;

int a[maxn];
int n,k;
ll m;

bool check(int x){
    ll ans=0;
    int num = 0;
    int j=1;
    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++;
            }
            num--;
            j++;
        }
    }
    return ans >= 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=1,r=1000000000;
        while(l<r){
            int mid = l+(r-l+1)/2;
            if(check(mid))l = mid;
            else r = mid-1;
        }
        printf("%d\n",l);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章