求指定区间内与n互素的数的个数 容斥原理

题意:给定整数n和r,求区间[1, r]中与n互素的数的个数。

使, 1...n, gcd(i,n)1log(max(i,n)),rlog(max(i,n))
r


[1,r]n
nPi(i=1...k), , 
, 

6223(使)
k, rk[1,r]k

详细见容斥定理

详细代码如下

int solve(int r, int n) {
    vector<int>p;
    p.clear();
    for(int i = 2; i*i <= n; ++i) {
        if(n % i == 0) {
            p.push_back(i);
            while(n % i == 0) n /= i;
        }
    }
    if(n > 1) p.push_back(n); //可能n也是素数
    int sum = 0;
    for(int msk = 1; msk < (1<<p.size()); ++msk) {
        int mult = 1, bits = 0;
        for(int i = 0; i < p.size(); ++i) {
            if(msk & (1<<i)) { //选择了第i个素数因子 
                bits++; 
                mult *= p[i];
            }
        }
        int cur = r / mult;
        if(bits & 1) sum += cur;
        else sum -= cur;
    } 
    return r - sum;
}

n, r

如有不当之处欢迎指出!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值