题解 P2568 【GCD】
那么答案是什么呢?
我们考虑每个质数
所以
对于每一个
所以此题答案就是
先介绍一些
积性函数(常见的有)
当然,还有
积性函数的性质:若
2.若
3.若
4.
所以,现在问题就转化为了怎样快速求
可以联想到欧拉筛法,因为可以在
若对于
1.若
2.若不互质,设
所以,预处理
for (int i=2;i<=n;++i){
if (is_prime[i]) phi[i]=i-1,prime[++prime_num]=i;
for (int j=1;j<=prime_num&&prime[j]*i<=n;++j){
is_prime[prime[j]*i]=0;
if (__gcd(prime[j],i)==1) phi[prime[j]*i]=phi[prime[j]]*phi[i];
else phi[prime[j]*i]=prime[j]*phi[i];
if (i%prime[j]==0) break;
}
}
做一下前缀和就可以了
最后提醒一句,
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=10000005;
bool is_prime[N];
int n,prime_num,prime[N],phi[N];
long long sum[N];
int main(){
scanf("%d",&n);
memset(is_prime,1,sizeof(is_prime));
is_prime[1]=0;phi[1]=1;
for (int i=2;i<=n;++i){
if (is_prime[i]) phi[i]=i-1,prime[++prime_num]=i;
for (int j=1;j<=prime_num&&prime[j]*i<=n;++j){
is_prime[prime[j]*i]=0;
if (__gcd(prime[j],i)==1) phi[prime[j]*i]=phi[prime[j]]*phi[i];
else phi[prime[j]*i]=prime[j]*phi[i];
if (i%prime[j]==0) break;
}
}
for (int i=1;i<=n;++i) sum[i]=sum[i-1]+phi[i];
long long ans=0;
for (int i=1;i<=prime_num&&prime[i]<=n;++i)
ans+=(sum[n/prime[i]]<<1)-1;
printf("%lld\n",ans);
return 0;
}