Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N)。
Input
一个整数,为N。
Output
一个整数,为所求的答案。
Sample Input
6
Sample Output
15
Hint
【数据范围】
对于60%的数据,0
思路
枚举哪些数作为
i
i
和的
gcd
g
c
d
,则有
f(N)=∑d|Nφ(Nd)∗d
f
(
N
)
=
∑
d
|
N
φ
(
N
d
)
∗
d
为答案
由于是积性函数,素数次幂欧拉值可以O1得到 总时间复杂度
O(n−−√)
O
(
n
)
代码
#include<iostream>
#include<cstdio>
#include<assert.h>
using namespace std;
typedef long long ll;
int main()
{
//ios::sync_with_stdio(false);
ll n;
while(scanf("%lld",&n)!=EOF)
{
//if(n==1)
ll ans=1;
int times=0;
for(int i=2;i*i<=n;++i){
if(n%i==0){
times++;
assert(times<=(1<<16));
ll num=0;
ll res=0;
ll up=1;
while(n%i==0){
num++;
n/=i;
up*=i;
}
//i^num
res=res+1*up+(i-1)*up/i;//0 1单独计算
up/=i;
ll phi=i-1;
for(int j=2;j<=num;++j){
phi*=i;
up/=i;
res+=phi*up;
}
ans*=res;
}
}
if(n>=1){
ans*=(n+n-1);
}
cout<<ans<<endl;
}
return 0;
}