计算两个数的超表中的第N个数

Calculate Nth number in supertable of two numbers

本文关键字:个数 两个 计算      更新时间:2023-10-16

两个数字表ab按升序写入并合并在一起,并删除重复项。现在的问题是在这个超表中找到比O(n)复杂度更好的nth数。

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

如果我理解得对,那么arays AB的指定如下:

A[i] = a*i
B[i] = b*i

那么应用二进制搜索至少可以得到CCD_ 8解。

考虑一些值x。它是否会超出您的n元素?您需要确定联合序列中x之前有多少元素。这很容易做到:从Ax/a元素,从Bx/b元素,但oops——我们已经计算了两次常见元素。共有x/d个元素,其中dab的最小公乘,所以我们减去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)解决方案也可用