Description
Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.
“Oh, I know, I know!” Longge shouts! But do you know? Please solve it.
Input
Input contain several test case.
A number N per line.
Output
For each N, output ,∑gcd(i, N) 1<=i <=N, a line
Sample Input
2
6
Sample Output
3
15
设
f
(
N
)
=
∑
i
=
1
N
g
c
d
(
i
,
N
)
设f(N)=\displaystyle\sum_{i=1}^{N}{gcd_{(i,N)}}
设f(N)=i=1∑Ngcd(i,N)可知f(n)是积性函数(此处不给出证明)
不妨令N的素因子分解式N=
p
1
a
1
p_{1}^{a_{1}}
p1a1·
p
2
a
2
p_{2}^{a_{2}}
p2a2·…·
p
n
a
n
p_{n}^{a_{n}}
pnan(
p
i
p_{i}
pi是素数)
所以由积性函数的性质可知
f
(
N
)
=
f
(
p
1
a
1
)
⋅
f
(
p
2
a
2
)
⋅
…
⋅
f
(
p
n
a
n
)
f(N)=f(p_{1}^{a_{1}})·f(p_{2}^{a_{2}})·…·f(p_{n}^{a_{n}})
f(N)=f(p1a1)⋅f(p2a2)⋅…⋅f(pnan),
对
f
(
p
1
a
1
)
=
∑
i
=
1
p
1
a
1
g
c
d
(
i
,
p
1
a
1
)
对f(p_{1}^{a_{1}})=\displaystyle\sum_{i=1}^{p_{1}^{a_{1}}}{gcd_{(i,p_{1}^{a_{1}})}}
对f(p1a1)=i=1∑p1a1gcd(i,p1a1)
和
p
1
a
1
p_{1}^{a_{1}}
p1a1互素的数的个数有
φ
\varphi
φ(
p
1
a
1
p_{1}^{a_{1}}
p1a1)个,他们的最大公因数是1;
和
p
1
a
1
p_{1}^{a_{1}}
p1a1的最大公因数为
p
1
p_{1}
p1的数都可以写成
p
1
⋅
k
p_{1}·k
p1⋅k且k与
p
1
p_{1}
p1互素,故k可以取[1,
p
1
a
1
−
1
p_{1}^{a_{1}-1}
p1a1−1]中与
p
1
p_{1}
p1互素的数,而与
p
1
a
1
−
1
p_{1}^{a_{1}-1}
p1a1−1不互素的数均为
p
1
p_{1}
p1的倍数,所以满足条件的k有
φ
\varphi
φ(
p
1
a
1
−
1
p_{1}^{a_{1}-1}
p1a1−1)个,即和
p
1
a
1
p_{1}^{a_{1}}
p1a1的最大公因数为
p
1
p_{1}
p1的数有
φ
\varphi
φ(
p
1
a
1
−
1
p_{1}^{a_{1}-1}
p1a1−1)个;
依此类推……
和
p
1
a
1
p_{1}^{a_{1}}
p1a1的最大公因数为
p
1
a
1
−
1
p_{1}^{a_{1}-1}
p1a1−1的数有
φ
(
p
1
)
\varphi(p_{1})
φ(p1)个。
和
p
1
a
1
p_{1}^{a_{1}}
p1a1的最大公因数为
p
1
a
1
p_{1}^{a_{1}}
p1a1的数有
φ
\varphi
φ(1)=1个。
将它们求和,即可得
f
(
p
1
a
1
)
=
1
⋅
φ
(
p
1
a
1
)
+
p
1
⋅
φ
(
p
1
a
1
−
1
)
+
…
+
p
1
a
1
−
1
⋅
φ
(
p
1
)
+
p
1
a
1
⋅
φ
(
1
)
f(p_{1}^{a_{1}})=1·\varphi(p_{1}^{a_{1}})+p_{1}·\varphi(p_{1}^{a_{1}-1})+…+p_{1}^{a_{1}-1}·\varphi(p_{1})+p_{1}^{a_{1}}·\varphi(1)
f(p1a1)=1⋅φ(p1a1)+p1⋅φ(p1a1−1)+…+p1a1−1⋅φ(p1)+p1a1⋅φ(1)
由欧拉函数公式
φ
(
x
)
=
x
∏
i
=
1
n
(
1
−
1
p
i
)
\varphi(x)=x\displaystyle\prod_{i=1}^{n}(1-\frac{1}{p_{i}})
φ(x)=xi=1∏n(1−pi1)
(其中
p
i
p_{i}
pi是x的所有质因数,x是不为0的整数)
所以
f
(
p
1
a
1
)
=
a
1
⋅
p
1
a
1
⋅
(
1
−
1
p
1
)
+
p
1
a
1
f(p_{1}^{a_{1}})=a_{1}·p_{1}^{a_{1}}·(1-\frac{1}{p_{1}})+p_{1}^{a_{1}}
f(p1a1)=a1⋅p1a1⋅(1−p11)+p1a1
=
p
1
a
1
[
a
1
(
1
−
1
p
1
)
+
1
]
=p_{1}^{a_{1}}[a_{1}(1-\frac{1}{p_{1}})+1]
=p1a1[a1(1−p11)+1]
所以
f
(
N
)
=
f
(
p
1
a
1
)
⋅
f
(
p
2
a
2
)
⋅
…
⋅
f
(
p
n
a
n
)
f(N)=f(p_{1}^{a_{1}})·f(p_{2}^{a_{2}})·…·f(p_{n}^{a_{n}})
f(N)=f(p1a1)⋅f(p2a2)⋅…⋅f(pnan)
=
N
⋅
[
1
+
a
1
(
1
−
1
p
1
)
]
⋅
…
⋅
[
1
+
a
n
(
1
−
1
p
n
)
]
N·[1+a_{1}(1-\frac{1}{p_{1}})]·…·[1+a_{n}(1-\frac{1}{p_{n}})]
N⋅[1+a1(1−p11)]⋅…⋅[1+an(1−pn1)]
=
N
∑
i
=
1
n
(
1
+
a
i
(
1
−
1
p
i
)
)
N\displaystyle\sum_{i=1}^{n}(1+a_{i}(1-\frac{1}{p_{i}}))
Ni=1∑n(1+ai(1−pi1))
解题代码如下,代码中为最大程度减少循环次数,还运用了定理:对任意正整数n,最多只有一个素因子大于 n \sqrt{n} n,且如果有素因子大于 n \sqrt{n} n,那么这个素因子的次数一定是1
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
int n;
long long ans;
while(cin>>n) {
ans=n;
int b=sqrt(1.0*n);//sqrt的形参是double类型的。
for(int i=2; i<=b; i++)
{
if(n%i==0)//说明i是其中一个素因子
{
int a=0;
while(n%i==0)//计算对应这个素因子的次数
{
n/=i;
a++;
}
ans=ans+ans*a*(i-1)/i;//技巧:像此题除法一定要保证是整除
}
}
if(n!=1)
ans=ans+ans*(n-1)/n;//此处是在判断是否存在大于根号n的质因子
cout<<ans<<endl;
}
return 0;
}