878. 第 N 个神奇数字

如果正整数可以被 A 或 B 整除,那么它是神奇的。

返回第 N 个神奇数字。由于答案可能非常大,返回它模 10^9 + 7 的结果

 

示例 1:

输入:N = 1, A = 2, B = 3
输出:2

示例 2:

输入:N = 4, A = 2, B = 3
输出:6

示例 3:

输入:N = 5, A = 2, B = 4
输出:10

示例 4:

输入:N = 3, A = 6, B = 4
输出:8

 

提示:

  1. 1 <= N <= 10^9
  2. 2 <= A <= 40000
  3. 2 <= B <= 40000

思路:

神奇数字的产生:A的倍数,B的倍数,A和B的公倍数

那么根据容斥原理,给定一个数N,那么小于等于N的数字中,神奇数字的个数应该为N/A+N/B-N/AB的最小公倍数

而最小公倍数等于A*B/AB的最大公约数;

建立一个大区间,通过二分法来求解,大区间的mid,可以知道mid左边有mid/A个A,mid/B个B ,mid/G个AB的最小公倍数,mid/A+mid/B-mid/g就代表mid左边有多少个满足条件的数。然后二分法求解,直到找到一定个数的满足条件的数。

Code:

class Solution {
public:
 int gcd(int a,int b)//求最大公约数
    {
        return b==0?a:gcd(b,a%b);
    }
    int nthMagicalNumber(int N, int A, int B)
    {
        long long low=0,high=2000000000000000000L;
        int g=A*B/gcd(A,B);
        while(low<high)
        {
            long long mid=(low+high)/2;
            long long t=mid/A+mid/B-mid/g;
            if(t<N)
            {
                low=mid+1;
            }
            else
                high=mid;
        }
        return (int)(high%1000000007);
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值