HDU 6231 K-th Number CCPC2017 Harbin(二分答案)
来源:互联网 发布:手机淘宝卖东西怎么弄 编辑:程序博客网 时间:2024/06/06 12:43
K-th Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 17 Accepted Submission(s): 9
Problem Description
Alice are given an array
Now Alice want to build an array
Initially, the array B is empty. Consider each interval in array A. If the length of this interval is less than
In fact Alice doesn't care each element in the array B. She only wants to know the
Input
The first line is the number of test cases.
For each test case, the first line contains three positive numbers
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
Sample Input
25 3 22 3 1 5 43 3 15 8 2
Sample Output
32
Source
2017中国大学生程序设计竞赛-哈尔滨站-重现赛(感谢哈理工)
其实这题非常的不应该,非常非常不应该,因为自己做过类似的题目。17年湖南多校,大笨龙那题:传送门
但是都说了赛场上有毒,没怎么想,而且还想偏了,去想HDU多校赛那题了……然后就没有然后了……
回顾一下这个思想,关于第K大的判定问题,我们通常可以用二分答案加上模糊化处理。即,我们二分枚举最后的答案,然后把所有的数字模糊化处理,就是把数字分为大于等于答案的和小于答案的。大于的表示为1,小于的表示为0。问题模糊化之后就可省去很多时间了。
比如说这题的,把所有的区间第K大放到一个新的数组中,然后排序,输出第M大。我二分枚举这个最后的第M大,假设为X,那么我们需要只考虑大于等于X的数字。于是相当于我们只需要判断在这个新数组中,大于等于X的数字的数量是否大于M,也即第K大大于等于X的区间的数量是否大于M。最后变成了统计第K大大于X的区间。模糊化处理之后,我们发现,如果用0、1替代,我们就能通过区间和来判定该区间的第K大是否大于等于X。如果区间和大于等于K,那么第K大就大于等于X。统计数量也相对简单了很多。我们枚举左端点,然后找右端点,知道找到一个点恰好区间和为K,那么以这个点以及这个点之后的所有点为右端点的区间第K大肯定大于等于X。这样子做看似还是O(N^2)的,但是我们发现,当左端点右移一格之后,这个右端点的最小值是不下降的,也就是说可以用类似离线处理的方法,做到用O(N)的复杂度统计。于是此题就迎刃而解了,需要注意的是,这个M可能比较大,需要用LL,然后统计区间的时候也要用LL。具体见代码:
#include <bits/stdc++.h>#define LL long long#define N 100010using namespace std;int n,k,tot,a[N],b[N],s[N];map<int,bool> mp; LL m;bool check(int x){ int p=1; LL res=0; for(int i=1;i<=n;i++) s[i]=s[i-1]+(a[i]>=x);//模糊化处理,同时计算前缀和 for(int i=1;i<=n;i++) { while(s[p]-s[i-1]<k&&p<n) p++;//找到使得区间和大于K的第一个点,即对应右端点的最小值 if (s[p]-s[i-1]!=k) break; res+=n-p+1;//之后的所有点都可以当作右端点 if (res>=m) return 1; } return res>=m;//判断区间数与M的关系}bool cmp(int a,int b){ return a>b;}int main(){ int T_T; cin>>T_T; while(T_T--) { mp.clear(); tot=0; scanf("%d%d%I64d",&n,&k,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if (!mp[a[i]]) { mp[a[i]]=1; b[++tot]=a[i]; } } sort(b+1,b+1+tot,cmp); int l=1,r=tot,mid,ans; while(l<=r) { mid=(l+r)>>1; if (check(b[mid])) ans=b[mid],r=mid-1; else l=mid+1; } printf("%d\n",ans); }}
- HDU 6231 K-th Number CCPC2017 Harbin(二分答案)
- HDU 6241 Color a Tree CCPC2017 Harbin(二分答案+上下界判定)
- HDU 6231 K-th Number(二分+尺取)
- 2017ccpc哈尔滨 hdu 6231 B k-th number 题解 二分答案+尺取法
- HDU 3943 —— K-th Nya Number(数位DP,二分答案)
- hdu6231 K-th Number(二分答案+尺取)
- HDU 3943 K-th Nya Number(数位dp+二分)
- K-th Number HDU
- HDU 6230 Palindrome CCPC2017 Harbin(Manacher+树状数组+离线处理)
- HDU 6231 K-th Number 尺取法
- 【poj 2104】K-th Number(整体二分+树状数组)
- K-th Nya Number (数位dp+二分)
- 2017CCPC哈尔滨 B:K-th Number(二分)
- poj2104 K-th Number(整体二分+树状数组)
- hdu 2104 K-th Number(静态求区间第k小+整体二分)
- POJ 2104 K-th Number 整体二分
- poj 2104 K-th Number[整体二分]
- POJ2104 K-th Number 【线段树+二分】
- Handler初体验(一)——下载文件并更新进度条
- Android ANR
- 1027. 打印沙漏(20)
- mysql5.7解压版安装
- 状态机跑飞的例子
- HDU 6231 K-th Number CCPC2017 Harbin(二分答案)
- win7系统休眠功能的关闭与启用
- 1133. Splitting A Linked List (25)
- 看了毁你三观的PCB设计理论 高速PCB外层还要不要覆铜了
- 【我的Java笔记】数据结构
- 1028. 人口普查(20)
- Log4J使用笔记
- C++——初始化列表
- 1029. 旧键盘(20)