题目
求
∑
x
=
1
n
−
1
[
gcd
(
x
,
n
)
=
1
]
⋅
x
\sum_{x=1}^{n-1}\big[\gcd(x,n)=1\big]\cdot x
x=1∑n−1[gcd(x,n)=1]⋅x
思路
根据
gcd
(
a
,
b
)
=
gcd
(
a
−
b
,
b
)
\gcd(a,b)=\gcd(a-b,b)
gcd(a,b)=gcd(a−b,b) 可知:
gcd
(
n
,
x
)
=
gcd
(
n
−
x
,
x
)
\gcd(n,x)=\gcd(n-x,x)
gcd(n,x)=gcd(n−x,x)
以及
gcd
(
n
,
n
−
x
)
=
gcd
(
x
,
n
−
x
)
\gcd(n,n-x)=\gcd(x,n-x)
gcd(n,n−x)=gcd(x,n−x)
所以说
gcd
(
n
,
x
)
=
gcd
(
n
,
n
−
x
)
\gcd(n,x)=\gcd(n,n-x)
gcd(n,x)=gcd(n,n−x) 。若二者都为
1
1
1 ,则提供一份
(
n
−
x
)
+
(
x
)
=
n
(n-x)+(x)=n
(n−x)+(x)=n 的贡献;若都不为
1
1
1 ,无话可说。
所以只需要找到有多少组即可。这是
φ
\varphi
φ 的范畴了。
代码
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std
;
typedef long long int_
;
inline int readint(){
int a
= 0; char c
= getchar(), f
= 1;
for(; c
<'0'||c
>'9'; c
=getchar())
if(c
== '-') f
= -f
;
for(; '0'<=c
&&c
<='9'; c
=getchar())
a
= (a
<<3)+(a
<<1)+(c
^48);
return a
*f
;
}
int getphi(int n
){
int res
= n
;
for(int i
=2; 1ll*i
*i
<=n
; ++i
)
if(n
%i
== 0){
res
-= res
/i
;
while(!(n
%i
)) n
/= i
;
}
if(n
> 1) res
-= res
/n
;
return res
;
}
int main(){
int n
; const int Mod
= 1e9+7;
while(~scanf("%d",&n
) && n
){
long long sy
= n
-getphi(n
)-(n
!=1);
sy
= (sy
>>1)*n
+(sy
&1)*(n
>>1);
printf("%lld\n",sy
%Mod
);
}
return 0;
}