# 【Project Euler】530 GCD of Divisors 莫比乌斯反演

【题目】GCD of Divisors

【题意】给定f(n)=Σd|n gcd(d,n/d)的前缀和F(n)，n=10^15。

【算法】莫比乌斯反演

【题解】参考：任之洲数论函数.pdf

$$F(n)=\sum_{i=1}^{n}\sum_{d|i}(d,\frac{i}{d})$$

$$F(n)=\sum_{d=1}^{n}d\sum_{i=1}^{n}\sum_{g|i}[(g,\frac{i}{g})=d]$$

$$F(n)=\sum_{d=1}^{n}d\sum_{i=1}^{\frac{n}{d^2}}\sum_{g|i}[(g,\frac{i}{g})=1]$$

$$F(n)=\sum_{d=1}^{n}d\sum_{i=1}^{\frac{n}{d^2}}\sum_{g|i}\sum_{d'|g \cap d'|\frac{i}{g}}\mu(d')$$

$$F(n)=\sum_{d=1}^{n}\sum_{d'=1}^{n}d*\mu(d')\sum_{i=1}^{\frac{n}{d^2}}\sum_{g|i}[d'|g \cap d'|\frac{i}{g}]$$

$$F(n)=\sum_{d=1}^{n}\sum_{d'=1}^{n}d*\mu(d')\sum_{i=1}^{\frac{n}{(dd')^2}}\sum_{g|i}1$$

$$F(n)=\sum_{d=1}^{n}\sum_{d'=1}^{n}d*\mu(d')\sum_{i=1}^{\frac{n}{(dd')^2}}\sigma_0(i)$$

$$F(n)=\sum_{d=1}^{\sqrt{n}}\sum_{g|d}g*\mu(\frac{n}{g})\sum_{i=1}^{\frac{n}{(dd')^2}}\sigma_0(i)$$

$$F(n)=\sum_{d=1}^{\sqrt{n}}\varphi(d)\sum_{i=1}^{\frac{n}{(dd')^2}}\sigma_0(i)$$

$$\sum_{i=1}^{n}\sigma_0(i)=\sum_{i=1}^{n}\sum_{d|i}1=\sum_{i=1}^{n}\sum_{j=1}^{\frac{n}{i}}1$$

$$\sum_{i=1}^{n}\sigma_0(i)=\sum_{i=1}^{n}\left \lfloor \frac{n}{i} \right \rfloor$$

$$\sum_{i=1}^{\sqrt{n}}O(\sqrt{\frac{n}{i^2}})=\sum_{i=1}^{\sqrt{n}}O(\frac{\sqrt{n}}{i})=O(\sqrt{n} ln \sqrt{n})$$

#include<cstdio>
#include<cmath>
#define int long long
const int maxn=32000000;
int phi[maxn],n,prime[maxn],tot;
int solve(int n){
int pos,sum=0;
for(int i=1;i<=n;i=pos+1){
pos=n/(n/i);
sum+=(pos-i+1)*(n/i);
}
return sum;
}
#undef int
int main(){
#define int long long
scanf("%lld",&n);
int ans=1*solve(n),N=(int)sqrt(n)+1;phi[1]=1;//1
for(int i=2;i<=N;i++){
if(!phi[i])phi[prime[++tot]=i]=i-1;
for(int j=1;j<=tot&&i*prime[j]<=N;j++){
if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
ans+=phi[i]*solve(n/(i*i));
}
printf("%lld",ans);
return 0;
}
View Code

posted @ 2018-03-01 14:29  ONION_CYC  阅读(259)  评论(0编辑  收藏