K-th Number

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;
}
原文地址:https://www.cnblogs.com/LeafLove/p/13459143.html