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;
}

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