K-th Number
Problem:
Alice are given an array A[1..N] with N numbers.
Now Alice want to build an array B by a parameter K as following rules:
Initially, the array B is empty. Consider each interval in array A. If the length of this interval is less than K, then ignore this interval. Otherwise, find the K-th largest number in this interval and add this number into array B.
In fact Alice doesn't care each element in the array B. She only wants to know the M-th largest element in the array B. Please help her to fi nd this number.
Input:
The first line is the number of test cases. For each test case, the first line contains three positive numbers N(1≤N≤105);K(1≤K≤N);M.
The second line contains N numbers (Ai(1≤Ai≤10^9)).
It's guaranteed that M is not greater than the length of the array B.
Output:
For each test case, output a single line containing the M-th largest element in the array B.
Example:
Input
2
5 3 2
2 3 1 5 4
3 3 1
5 8 2
Output
3
2
Solution:
二分+尺取
Code:
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int maxn = 111111;
int a[maxn], n, k;
ll m;
ll chack(int x)
{
ll ans = 0;
int l = 0, r = 0, ct = 0;
//尺取法
while (r < n) {
if (a[r] >= x) {
ct++;
}
if (ct >= k) {
ans += n - r;
while (a[l] < x) {
l++;
ans += n - r;
}
ct--; l++;
}
r++;
}
return ans;
}
int main()
{
int t;
cin >> t;
while (t--) {
cin >> n >> k >> m;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int l = 1, r = 1e9+10, ans = -1;
while (l < r) {
int mid = (l + r) >> 1;
if (chack(mid) >= m) {
ans = mid;
l = mid + 1;
}
else
r = mid;
}
cout << ans << endl;
}
return 0;
}