HDU 6231 K-th Number——二分+尺取
阿新 • • 發佈:2018-12-09
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; }