HDU 4135 Co-prime(容斥原理)

题目链接
题意

给你三个整数a,b,c求[a,b]区间内与n互质数个数

思路

即求[a,b]区间内与n不互质数个数,即将n进行素数拆分
一个数是某个拆分数的倍数即不互质,如wtf/素数pri 为 1到wtf间与pri不互质的个数)
素数拆分有很多,会重复计数,用容斥原理剔除。
ans = r-(l-1) - ( solve( r ) - solve( l-1 ) )

代码(含两种版本)
递归版
#include <stdio.h>

#define ll long long

ll l, r, num[100], len;

ll dfs(ll n, ll x)
{
    ll tmp = 0;
    for(ll i = x; i < len; ++i) tmp += n/num[i] - dfs(n/num[i], i+1);
    return tmp;
}

int main()
{
    ll t, ca = 1, n;
    for(scanf("%lld",&t); ca <= t; ++ca)
    {
        scanf("%lld%lld%lld",&l,&r,&n);
        len = 0;
        for(ll i = 2; i*i <= n; ++i)
        {
            if(n%i == 0)
            {
                num[len++] = i;
                while(n%i == 0) n /= i;
            }
        }
        if(n > 1) num[len++] = n;
        printf("Case #%lld: %lld\n",ca, r-(l-1) - (dfs(r, 0) - dfs(l-1, 0)));
    }
    return 0;
}

二进制版本
#include <stdio.h>

#define ll long long

ll l, r, num[100], len;

ll solve(ll n)
{
    ll ans = 0;
    for(ll i = 1; i < (1ll<<len); ++i)
    {
        ll tmp = 0, wtf = 1;
        for(ll j = 0; j < len; ++j)
        {
            if((1ll<<j) & i)
            {
                wtf *= num[j];
                tmp ^= 1;
            }
        }
        ans += tmp ? n/wtf : -n/wtf;
    }
    return ans;
}

int main()
{
    ll t, ca = 1, n;
    for(scanf("%lld",&t); ca <= t; ++ca)
    {
        scanf("%lld%lld%lld",&l,&r,&n);
        len = 0;
        for(ll i = 2; i*i <= n; ++i)
        {
            if(n%i == 0)
            {
                num[len++] = i;
                while(n%i == 0) n /= i;
            }
        }
        if(n > 1) num[len++] = n;
        printf("Case #%lld: %lld\n",ca, r-(l-1) - (solve(r) - solve(l-1)));
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值