AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=2705
【题解】
设gcd(m,n)=k的m的个数为s(k),k为n的约数
则ans=sigma(k*s(k))
由gcd(m,n)=k,gcd(m/k,n/k)=1,所以s(k)=phi(n/k)
时间复杂度O(nlogn)
/*************
bzoj 2705
by chty
2016.11.4
*************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m,ans;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
ll phi(ll x)
{
ll sum=x;
for(ll i=2;i<=m;i++)
{
if(x%i==0) sum=sum/i*(i-1);
while(x%i==0) x/=i;
}
if(x>1) sum=sum/x*(x-1);
return sum;
}
int main()
{
freopen("cin.in","r",stdin);
freopen("cout.out","w",stdout);
n=read();
m=(ll)sqrt(n*1.0);
for(ll i=1;i<=m;i++)
if(n%i==0)
{
ans+=i*phi(n/i);
if(i*i<n) ans+=(n/i)*phi(i);
}
printf("%lld\n",ans);
return 0;
}