HDU 6231 K-th Number——二分+尺取

版权声明:欢迎大家转载,转载请注明出处 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;
}

猜你喜欢

转载自blog.csdn.net/hao_zong_yin/article/details/82663618