题意略。
思路: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 */