leetcode 1201. 丑数 III(二分+容斥算1-n有多少个可被a或b或c整除的数)

题目
在这里插入图片描述在这里插入图片描述

二分,判断1-mid 有多少个数可被a,或b,或c整除。(容斥)
注意的是,当cal(mid)==n时,区间应该左移,high=mid-1;
因为cal(mid)==n时,mid可能并不是合法的数,既然1到mid有n个合法的数,那么[1,mid-1],肯定有合法的数。而比mid大的数,或许cal()它可能是n,但也是不合法的,后面有一个合法的话就是cal()=n+1了。

class Solution {
#define ll long long
public:
    int a,b,c;
    int gcd(int x,int y){return y?gcd(y,x%y):x;}
    ll get(ll x,ll y){return x*y/gcd(x,y);}
    ll get(ll x,ll y,ll z){return get(get(x,y),z);}
    int cal(ll n){//1-n中有多少被a,b,c整除的正整数
        ll x=get(a,b),y=get(a,c),z=get(b,c),o=get(a,b,c);
        return n/a+n/b+n/c-n/x-n/y-n/z+n/o;
    }
    int nthUglyNumber(int n, int a, int b, int c) {
        this->a=a,this->b=b,this->c=c;
        int low=1,high=2000000000,mid;
        while(low<=high){
            mid=((ll)low+high)>>1;//low+high会爆int
            int d=cal(mid);
            //d=n的时候,区间应该变小。。
            if(d>=n){//注意d=n的时候 比如n=4 a=2 b=3 c=4 cal(6)=4 cal(7)=4 cal(8)=5;
                if(d==n&&((mid%a==0)||(mid%b==0)||(mid%c==0))) return mid;
                high=mid-1;
            }
            else low=mid+1;
        }
        return -12345678912345;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值