leetcode 878 第 N 个神奇数字

关键词: 二分 容斥原理

题意描述

1. (a,b)的神奇数字:能被a或b整除
2. 第N个神奇数字:排序的第N个

思路分析

判断一个数是不是神奇数字是容易的。那么判断区间[0,n]之间有多少个神奇数字呢?

思考1:神奇数字有哪些种类?

神奇数字集合分布

  1. 能被a整除
  2. 能被b整除
  3. 能同时被a,b整除,即能被lcm(a,b)(a,b的最小公倍数)

思考2:如何求得区间[0,n]之间神奇数字的个数?

M_{(a,b)}(n)=M_a(n)+M_b(n)-M_{lcm(a,b)}(n)

思考3: 一个数t是否最终结果如何判断?

M(t)=NM(t-1)<N

代码实现

class Solution {
public:
    const int MOD=1e9+7;
    typedef long long LL;
    int nthMagicalNumber(int N, int A, int B) {
        LL l=1;
        LL r = 1e18;
        int ab = 1ll * A *B/gcd(A,B);   // 最小公倍数
        while(l<r){
            LL m = (r+l)/2;
            LL cnt =0;
            cnt+= m/A+m/B-m/ab;
            if(cnt>=N) r=m;
            else l=m+1;
        }
        return l%MOD;
    }
};

小结

二分查找的主要套路:

  • 数据规模大,O(nlogn)是上限
  • 数据有序,或者构造后(前缀和,后缀和)有序
  • 分段,找分割点
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容