两个数组各个数相加或相乘变成一个矩阵求第K大
input
1<=T<=20
1<=n<=100000,1<=k<=n*n
a1 a2 ... an 0<ai<=10000
b1 b2 ... bn 0<bi<=10000
output
第k大的数(包含重复)
做法:类似字符串的编码解码,这里是解码过程,将k解码为对应的01串,把第K大的数看成一个01串,统计出比1000000000000000000000000000000000大的数有多少个,从而确定第一个数是0还是1,然后第二位也是这样,不断的重复直到找到第K大的数,复杂度为O(2nlog(maxa*maxb))
a[0]*b[0]<=a[0]*b[1]<=...<=a[0]*b[n-1]
a[1]*b[0]<=a[1]*b[1]<=..<=a[1]*b[n-1]
...
a[n-1]*b[0]<=a[n-1]*b[1]<=...<=a[n-1]*b[n-1]
同时从上到下也有这样的性质,所以当a[i]*b[j]>val时,a[i+1]*b[j]>val
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXN = ; int a[MAXN], b[MAXN];
int T, n;
LL k; bool check(int val)//统计比val小的数的个数cnt,看cnt比k大还是比k小
{
LL cnt = ;
for(int i = , j = n - ; i < n; ++i)
{
while(j >= && a[i] * b[j] > val) --j;
cnt += j + ;//j+1指每一列数中比val大的数
}
return cnt >= k;
} int solve()//二分查找第k大的数
{
int l = a[] * b[], r = a[n - ] * b[n - ];
while(l < r)
{
int mid = (l + r) >> ;
if(!check(mid)) l = mid + ;
else r = mid;
}
return l;
} int main()
{
scanf("%d", &T);
while (T--)
{
scanf("%d%I64d", &n, &k);
for(int i = ; i < n; ++i) scanf("%d", &a[i]);
for(int i = ; i < n; ++i) scanf("%d", &b[i]);
sort(a, a + n);
sort(b, b + n);
k = (LL)n * n - k + ;
printf("%d\n", solve());
}
return ;
}
input
1<=T<=10
1<=n,k<=100000
a1 a2 ... an an<=10^9
b1 b2 ... bn bn<=10^9
output
第k小的数(不包含重复)
做法:用大白上的有限队列做法,先将第一列的数放进从小到大的优先队列,每出队一个数就将同一行的下一个数放入队列
a[0]+b[0]<=a[0]+b[1]<=...<=a[0]+b[n-1]
a[1]+b[0]<=a[1]+b[1]<=..<=a[1]+b[n-1]
...
a[n-1]+b[0]<=a[n-1]+b[1]<=...<=a[n-1]+b[n-1]
两个数组各个数相加或相乘变成一个矩阵求第K大的更多相关文章
- ACM_求第k大元素(两次二分)
求第k大 Time Limit: 6000/3000ms (Java/Others) Problem Description: 给定两个数组A和B,大小为N,M,每次从两个数组各取一个数相乘放入数组C ...
- poj 2985 The k-th Largest Group 树状数组求第K大
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8353 Accepted ...
- 无序数组求第K大的数
问题描述 无序数组求第K大的数,其中K从1开始算. 例如:[0,3,1,8,5,2]这个数组,第2大的数是5 OJ可参考:LeetCode_0215_KthLargestElementInAnArra ...
- HDU 5249 离线树状数组求第k大+离散化
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- 牛客网2016.4.11(两个数相加为sum/计数一个int型的二进制有多少个1/二叉树是否左右对称)
求最小的两个数相加为sum //求最小的两个数相加为sum public ArrayList<Integer> FindNumbersWithSum(int [] array,int su ...
- 无序数组求第k大/第k小的数
根据http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html 博客中所总结的7种解法,我挑了其中的解法3和解法6进行了实现. 解法3: ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- 分别实现数组所有元素相加、相乘、相与——FP 风格
var ops = { "plus": (x,y)=>x+y, "mul" : (x,y)=>x*y, "and" : (x,y ...
- python的reduce函数的使用方法详解以及使用案例,相加,相乘(处理一个序列,然后把序列进程合并操作)
1.求列表的数字相加之和,还是之前的习惯,写for循环来实现 num_1=[1,2,3,4,5,6,7,8,9] a=0 for n in num_1: #a=a+n a+=n print (a) C ...
随机推荐
- geom设置—条形图
条形图可能是所有图形里面最基本的图形了,虽然很简单,在R里面有些地方不注意,还是会很容易出错. geom_bar()的基本参数情况 geom_bar(mapping = NULL, data = NU ...
- PHP7新功能及语法变化总结
1.标量类型声明有两种模式: 强制 (默认) 和 严格模式. 现在可以使用下列类型参数(无论用强制模式还是严格模式): 字符串(string), 整数 (int), 浮点数 (float), 以及布尔 ...
- Ubuntu14.04下手动建立快捷方式
先在桌面创建一个文件:文件内容如下 [Desktop Entry]Encoding=UTF-8Name=eclipseComment=eclipse ideExec=/home/mars/eclips ...
- Excel补全日期(日期按顺序补全)
1.给出的数据 2.想补全缺失的日期,比如2015/3/1,2015/3/2,... 1)在D列输入完整的日期,如下图所示: 2)在E2处写函数“=IF(ISERR(VLOOKUP(D2,B:C,2, ...
- css遗漏
对于float浮动 子级元素浮动之后,因为元素脱离了文档流所以父级元素的高度不会auto而是变成0的解决方案 父级元素增加伪类 父级:after{ content:""; disp ...
- qsort函数辅助函数compare函数的编写
qsort的第四个参数,辅助函数compare的关于不同排序对象的不同写法: 一.对int类型数组排序 ]; int compare(const void *a, const void *b) { r ...
- 移动端touch事件影响click事件的相关解决方法
preventDefault()的方法,阻止事件的默认行为. 在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend -->cl ...
- Fiddler AutoResponder正则替换
今天感冒,写简单些. Fiddler AutoResponder正则替换: regex:(?inx).+20150826_1_1_386.mp4/playlist.m3u8.*$ .表示任意字符 *: ...
- 使用timer定时器,防止事件重入
首先简单介绍一下timer,这里所说的timer是指的System.Timers.timer,顾名思义,就是可以在指定的间隔是引发事件.官方介绍在这里,摘抄如下: 1 2 Timer 组件是基于服务器 ...
- Subordinates
Subordinates time limit per test 1 second memory limit per test 256 megabytes input standard input o ...