版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/82663618
m要开long long,太苟了
首先二分答案,对于二分到的一个数x,我们要判断大于等于x的数做第k大的区间是否有m个,可以用尺取法,枚举每个左界,对于一个左界求一个右界,使得区间内大于等于x的数有k个,这样本次枚举就可以为答案贡献(n-r+1)。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int T, n, k;
ll m;
int a[maxn], b[maxn];
bool judge(int x) {
int l = 1, r = 0, cnt = 0;
ll ans = 0;
while (r <= n) {
while (r <= n && cnt != k) if (a[++r] >= x) cnt++;
while (cnt == k) {
ans += (n - r + 1);
if (a[l++] >= x) cnt--;
}
}
return ans >= m;
}
void solve() {
int l = 1, r = n;
while (l <= r) {
int mid = (l + r)>>1;
if (judge(b[mid])) l = mid + 1;
else r = mid - 1;
}
printf("%d\n", b[r]);
}
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d%d%lld", &n, &k, &m);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
sort(b+1, b+1+n);
a[n+1] = 0;
solve();
}
return 0;
}