NC14301 K-th Number

题目

题目描述

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.

输入描述

The first line is the number of test cases. For each test case, the first line contains three positive numbers \(N(1≤N≤10^5)\) ; $K(1≤K≤N) $; \(M\) .

The second line contains \(N\) numbers \(A_i(1≤A_i≤10^9)\) .It's guaranteed that M is not greater than the length of the array B.

输出描述

For each test case, output a single line containing the M-th largest element in the array B.

示例1

输入

2
5 3 2
2 3 1 5 4
3 3 1
5 8 2

输出

3
2

题解

思路

知识点:二分。

二分 \(B\) 的第 \(m\) 大,其在 \(B\) 序列中的位置具有单调性,检验大于等于这个数的 \(A\) 中所以子区间第 \(k\) 大的数量,如果数量大于等于 \(m\) ,说明这个数小于等于答案;反之,肯定大于。

计算大于等于这个数的 \(A\) 中所以子区间第 \(k\) 大的数量,通过对 \(A\) 尺取法快速计算区间总数,得到这个数在 \(B\) 中的排位。

注意的是,对答案二分时,不需要严格要求 \(mid\) 是在数组中的数,因为 \(l\) 和 \(r\) 最终会收敛到一个分界点上,而分界点只可能出现在数组中的数,所以不必担心。

坑点是 \(B\) 数组的长度是会超 \(int\) 的,因此 \(m\) 也会超 \(int\) 而题目没给范围,是最坑的。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; int n, k;
ll m;///可能到 1e10,坑死了
int a[100007]; bool check(int mid) {/// 查询大于等于mid的第k大的数的数量是否大于等于m
ll sum = 0;
int i = 0, j = 0, cnt = 0;
while (i < n) {
while (j < n && cnt < k) {
if (a[j] >= mid) cnt++;
j++;
}
if (cnt == k) sum += n - j + 1;
if (a[i] >= mid) cnt--;
i++;
}
return sum >= m;
} bool solve() {
cin >> n >> k >> m;
for (int i = 0;i < n;i++) cin >> a[i];
int l = 1, r = 1e9;///不必担心mid不是数组中的数,因为最后收敛点一定在数组的某个数上
while (l <= r) {
int mid = l + r >> 1;
if (check(mid)) l = mid + 1; ///check为真说明 mid 小于等于答案
else r = mid - 1;
}
cout << r << '\n';///返回比最后一次小于等于答案的数的位置
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

最新文章

  1. rdesktop的使用方法
  2. CF #296 (Div. 1) A. Glass Carving 线段树
  3. IOC知识
  4. 仿it快播顶部button点击背景滑动切换的效果
  5. Mac下eclipse安装SVN插件
  6. using(){},Close(),Dispose()的区别
  7. ALV 行列 颜色
  8. iOS7 StatusBar 使用小结
  9. Oracle EBS使用adpatch工具打patch过程【Z】
  10. git 简单教程更新
  11. Scala 控制结构
  12. [bzoj1587] [Usaco2009 Mar]Cleaning Up 打扫卫生
  13. Java String的简单介绍
  14. Educational Codeforces Round 25 A,B,C,D
  15. day10--协成\异步IO\缓存
  16. 通过Parcelable协议传递数据出现系列错误
  17. How arduino IDE works?
  18. zufeoj Electrification Plan (最小生成树,巧妙设e[i][j]=0)
  19. DIY-组装
  20. Informatica 常用组件Filter之二 过滤条件

热门文章

  1. 二次封装这几个 element-ui 组件后,大大减少了我 CRUD 的时间
  2. RAID5加热备盘
  3. 如何用C/C++实现去除字符串头和尾指定的字符
  4. 【计算机网络】Stanford CS144 Lab Assignments 学习笔记
  5. 使用FastJson导出JSON
  6. Vue.js 3.x 中跨层级组件如何传递数据?
  7. Mysql数据库基础_复习思维导图
  8. vue - Vue脚手架(终结篇)/ vue动画
  9. Linux下MySQL表名区分大小写
  10. [codeforces] 暑期训练之打卡题(三)