UOJ #576. 积的第K小数
【题目描述】:
有两个正整数数列,元素个数分别为N和M。从两个数列中分别任取一个数相乘,这样一共可以得到N×M个数,询问这N×M个数中第K小数是多少。
【输入描述】:
第一行为三个正整数N,M和K。
第二行为N个正整数,表示第一个数列。
第三行为M个正整数,表述第二个数列。
【输出描述】:
一个正整数表示第K小数。
【样例输入1】:
2 3 4
1 2
2 1 3
【样例输出1】:
3
【样例输入2】:
5 5 18
7 2 3 5 8
3 1 3 2 5
【样例输出2】:
16
【时间限制、数据范围及描述】:
时间:1s 空间:128M
| 编号__ | N______ | M_________ | K______________ | 元素大小(≤) |
|---|---|---|---|---|
| 1 | 20 | 20 | 150 | 10^4 |
| 2 | 50 | 50 | 2000 | 10^4 |
| 3 | 100 | 80 | 5000 | 10^9 |
| 4 | 200 | 200 | 26000 | 10^9 |
| 5 | 10000 | 10000 | 50050000 | 10^4 |
| 6 | 1000 | 20000 | 9500000 | 10^4 |
| 7 | 1000 | 20000 | 10000500 | 10^9 |
| 8 | 2000 | 20000 | 190000 | 10^9 |
| 9 | 2000 | 20000 | 199000 | 10^9 |
| 10 | 20000 | 20000 | 210005000 | 10^4 |
| 11 | 20000 | 20000 | 210000 | 10^5 |
| 12 | 20000 | 20000 | 200000 | 10^9 |
| 13 | 20000 | 20000 | 220000500 | 10^5 |
| 14 | 20000 | 20000 | 199000500 | 10^9 |
| 15 | 200000 | 200000 | 180000 | 10^4 |
| 16 | 200000 | 200000 | 200000 | 10^9 |
| 17 | 2000 | 200000 | 100001500 | 10^9 |
| 18 | 200000 | 180000 | 19550000000 | 10^5 |
| 19 | 200000 | 200000 | 19900010000 | 10^9 |
| 20 | 200000 | 200000 | 20000010000 | 10^9 |
思路:
20分:暴力枚举+排序,注意long long
30分:和的第K小数改一下(堆);
满分:二分答案,假想一个由{x|x∈A}和{y|y∈B}(A={a1,a2,a3,a4...an},B={b1,b2,b3,b4...bn},已从小到大排序)组成的乘法表C={x*y|x∈A,y∈B},取中间的积进行二分。
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
long long k;
int n,m,a[N],b[N];
int cmp(const void *p1,const void *p2) {
return (*(int *)p1)-(*(int *)p2);
}
long long check(long long ans) {
int i;
long long s=0,top=m,gtmp;
for(int i=1; i<=n; i++) {
gtmp=ans/a[i];
while(top&&b[top]>gtmp)
top--;
s+=top;
}
return s;
}
int main () {
scanf("%d%d%lld",&n,&m,&k);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
for(int i=1; i<=m; i++)
scanf("%d",&b[i]);
qsort(a+1,n,sizeof(a[0]),cmp);
qsort(b+1,m,sizeof(b[0]),cmp);
long long ll=a[1]*(long long)b[1];
long long rr=a[n]*(long long)b[m],mid;
while(ll<rr) {
mid=(ll+rr)/2;
if(check(mid)>=k)
rr=mid;
else
ll=mid+1;
}
printf("%lld\n",ll);
return 0;
}

浙公网安备 33010602011771号