题目
AcWing 220. 最大公约数(通俗易懂&效率高) - AcWing
解释
- 本题目标是对于1-n每一个数在前面找它的互质数对(这个思想的证明思路可以看上文)
- 比如φ3=【(1,3),(2,3)】
- 那么满足题意的还可以有2φ3,3φ3,不超过n!
- 线性筛对素数进行预处理,以及预处理了欧拉函数φ1φ2φ3……
- 用sum对欧拉函数进行前缀和预处理
- 时间复杂度为O(n)
- 最后一步的k暂时没有读懂
代码段
#include<iostream>
#define ll long long
using namespace std;
const int N=1e7+10;
bool st[N];
ll primes[N],phi[N],sum[N];
ll n,cnt;
int main()
{
cin>>n;
for(int i=2;i<=n;i++)//线性筛预处理素数和欧拉函数
{
if(!st[i])
{
primes[cnt++]=i;
phi[i]=i-1;
}
for(int j=0;primes[j]*i<=n;j++)
{
st[primes[j]*i]=true;
if(i%primes[j]==0)
{
phi[primes[j]*i]=primes[j]*phi[i];
//困惑1欧拉函数的递推写法
break;
}
else
{
phi[primes[j]*i]=phi[i]*(primes[j]-1);
}
}
}
for(int i=2;i<=n;i++)
sum[i]=sum[i-1]+phi[i];
ll ans=0;
for(int j=0;j<cnt;j++)
{
int k=n/primes[j];
ans+=2*sum[k]+1;
//困惑2这里的k含义是什么
}
cout<<ans<<endl;
}