题目大意:求∑gcd(i, N)(1<=i <=N)
题解:
∑i=1ngcd(i,n)
∑
i
=
1
n
g
c
d
(
i
,
n
)
=∑d|nd∑i=1n[gcd(i,n)==d]
=
∑
d
|
n
d
∑
i
=
1
n
[
g
c
d
(
i
,
n
)
==
d
]
令n′=[n/d]
令
n
′
=
[
n
/
d
]
=∑d|nd∑i=1n′[gcd(i,n′)==1]
=
∑
d
|
n
d
∑
i
=
1
n
′
[
g
c
d
(
i
,
n
′
)
==
1
]
=∑d|nd∗ϕ(n′)
=
∑
d
|
n
d
∗
ϕ
(
n
′
)
因为范围太大没法筛,直接求就可以了
我的收获:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define ll long long
ll n,ans;
ll phi(ll x){
ll ret=x;
for(ll i=2;i*i<=x;i++)
if(x%i==0){ret-=ret/i;while(x%i==0) x/=i;}
if(x>1) ret-=ret/x;
return ret;
}
void work()
{
cin>>n;
for(ll i=1;i*i<=n;i++)
if(n%i==0){
ans+=i*phi(n/i);
if(i*i<n) ans+=(n/i)*phi(i);
}
cout<<ans<<endl;
}
int main()
{
work();
return 0;
}