HDU

来源:互联网 发布:火凤凰云计算拖欠工资 编辑:程序博客网 时间:2024/06/03 19:19

K-th Number



Problem Description
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(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.
 

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

Sample Input
25 3 22 3 1 5 43 3 15 8 2
 

Sample Output
32
 



题意:给你数列A,对于A的每一个区间,求第K大,插入到数列B中,最后再求数列B的第M大!


解题思路:二分答案+尺取法判断。看了题解才会,真的很巧妙,这都能二分。对于当前答案,如果当前答案作为第K大的区间的总数大于M,那么证明实际答案要比当前答案大,反之则小。如果这个能懂的话,就知道怎么二分了。难点变为怎么统计答案作为第K大的区间个数,这里用到了尺取法。尺取法很容易理解,跟着代码跑一边就懂了。




#include<iostream>#include<deque>#include<memory.h>#include<stdio.h>#include<map>#include<string.h>#include<algorithm>#include<vector>#include<math.h>#include<stack>#include<queue>#include<set>using namespace std;typedef long long int ll;int N,K;ll M;int a[100005];bool judge(int x){    ll ans=0;//区间个数    int num=0;//当前>x的数的个数    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++;        }    }    if(ans>=M)        return true;    else        return false;    }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;        int m;        while(l<r){            m=(l+r)/2;            if(judge(m))                l=m+1;            else                r=m;        }        printf("%d\n",l-1);    }    return 0;}




原创粉丝点击