Co-prime
B - Co-prime
参考:HDU 4135 Co-prime (容斥原理)
这个题利用的是容斥原理,同时也利用到了求质数个数的一个技巧—— 1~m 内与 n 不互质的个数为 m/n 个:
prime.clear();
    for(ll i=2;i*i<=n;++i)
    {
        if(n%i==0)
            prime.emplace_back(i);
        while (n%i==0)
            n/=i;
    }
    if(n>1) prime.emplace_back(n);
同时使用容斥原理的时候求各种组合的时候利用了二进制的技巧:
ll sum=0,siz=prime.size();
    for(ll i=1;i<(1<<siz);++i)  // i 为 1 时取 prime[0],i 为 101(二进制) 时取 prime[0] prime[2]
    {
        ll val=1,cnt=0;
        for(ll j=0;j<siz;++j)
            if(i&(1<<j))
                val*=prime[j],cnt++;
        if(cnt&1) sum+=x/val;
        else sum-=x/val;
    }
代码(记得 long long .....因为这个 WA 了一发):
// Created by CAD on 2019/8/10.
#include <bits/stdc++.h>
using namespace std;
using pii=pair<int, int>;
using piii=pair<pair<int, int>, int>;
using ll=long long;
vector<ll> prime;
ll cal(ll x,ll n)
{
    prime.clear();
    for(ll i=2;i*i<=n;++i)
    {
        if(n%i==0)
            prime.emplace_back(i);
        while (n%i==0)
            n/=i;
    }
    if(n>1) prime.emplace_back(n);
    ll sum=0,siz=prime.size();
    for(ll i=1;i<(1<<siz);++i)
    {
        ll val=1,cnt=0;
        for(ll j=0;j<siz;++j)
            if(i&(1<<j))
                val*=prime[j],cnt++;
        if(cnt&1) sum+=x/val;
        else sum-=x/val;
    }
    return x-sum;
}
ll a,b,n;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    for(int cas=1;cas<=t;++cas)
    {
        cin>>a>>b>>n;
        cout<<"Case #"<<cas<<": "<<1ll*cal(b,n)-1ll*cal(a-1,n)<<endl;
    }
    return 0;
}
    CAD加油!欢迎跟我一起讨论学习算法,QQ:1401650042

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号