​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加油!欢迎跟我一起讨论学习算法