HDU 6231

题意略。

思路:1.对于这种静态的查问第M大是谁的问题,我们是可以采用二分后试探的方法,在试探时,我们要选取原数组中的值来验证。

2.对于一个给定的值x,我们只要知道在b数组中有多少数排在它前面就行。为了知道这个数,我们需要计算整个a数组能贡献多少,

我们枚举区间的左端来一个个计算贡献,由于后面的区间可以利用前面区间的结果,所以我们可以使用尺取法。

#include<bits/stdc++.h>
#define maxn 100010
using namespace std;
typedef long long LL;

int que[maxn],tail;
int store[maxn];
int N,K,T;
LL M;

void discrete(){
    sort(que,que + N);
    tail = unique(que,que + N) - que;
}
bool jud(int x){
    int t = -1;
    LL sum = 0;
    int cnt = 0;
    for(int h = 0;h < N;++h){
        while(cnt < K && t < N - 1){
            ++t;
            if(store[t] >= x) ++cnt;
        }
        if(cnt >= K) sum += LL(N - t);
        cnt -= (store[h] >= x);
    }
    return (sum >= (LL)M);
}

int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%lld",&N,&K,&M);
        for(int i = 0;i < N;++i){
            scanf("%d",&store[i]);
            que[i] = store[i];
        }
        discrete();
        int l = 0,r = tail - 1;
        while(l < r){
            int mid = (l + r + 1)>>1;
            int temp = que[mid];
            if(jud(temp)) l = mid;
            else r = mid - 1; 
        }
        printf("%d
",que[l]);
    }
    return 0;
}

/*
1
10 5 5
2 1 4 7 4 8 3 6 4 7
*/

 

原文地址:https://www.cnblogs.com/tiberius/p/8589085.html