编写两个数字表a
和b
并按升序合并在一起,并删除重复项。现在的问题是,在此超级数据中找到nth
数字比O(n)
复杂度更好。
Limits
1<=A, B<=1000
1<=N<=1000000000
这是我的意见,但它是O(n)
,任何人都可以提出更好的复杂性算法吗?谢谢!
#include <iostream>
#include<map>
using namespace std;
long long int min(long long a, long long b){
if(a<b) return a;
else return b;
}
long long int get( long long int a, long long int b, long long int count) {
long long int val = 0,i;
long long int nexta = a;
long long int nextb = b;
for ( i = 0; i < count; i++) {
val = min(nexta, nextb);
nexta = val < nexta ? nexta : (nexta + a);
nextb = val < nextb ? nextb : (nextb + b);
}
return val;
}
int main() {
int t;
cin >> t;
while(t--){
long long int a,b,n;
cin >> a>> b>> n;
cout << get(a,b,n)<< endl;
}
return 0;
}
示例: A = 3,B = 5
表A = 3,6,9,12,15,18等等
表B = 5,10,15,20等等
合并后:3,5,6,9,10,12,15,15,18,20等等
删除重复项:3,5,6,9,10,12,15,18,20等等
对于N = 2,超级表的第二元素是5
答案 0 :(得分:1)
如果我理解你,arays A
和B
指定如下:
A[i] = a*i
B[i] = b*i
然后您可以通过应用二进制搜索获得至少O(log N)
解决方案。
考虑一些价值x
。它会超出你的n
元素吗?您需要确定联合序列中的元素在x
之前的数量。它很容易完成:A
有x/a
个元素,B
有x/b
,但是oops ---我们已经计算了两次共同元素。有x/d
个公共元素,其中d
是a
和b
的最不常见的乘法,所以让我们减去x/d
。因此,如果x/a + x/b - x/d>=n
,那么x
至少是n
元素,否则它就在之前。
现在二进制搜索代码为(伪代码)
l = 0
r = a * n + 1
d = lcm(a,b)
while r-l>1
m = (r+l)/2
cnt = m/a + m/b - m/d
if cnt >= n
r = m
else l = m
your answer is r
甚至可以使用O(1)
解决方案