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