题目大意:
求 ∑ni=1gcd(i,n) ∑ i = 1 n g c d ( i , n )
思路:
题目描述绝对没有你想象的那么简单。
Input
I
n
p
u
t
4
Output O u t p u t
9
50分做法:直接求上式,时间复杂度
O(nlogn)
O
(
n
l
o
g
n
)
100分做法:
随便取一个数,找一下规律。
- 12
分解后为
- 1 2 3 4 1 6 1 4 3 2 1 12
再统计一下每个数字的个数。
- 1:4
- 2:2
- 3:2
- 4:2
- 6:1
- 12:1
不难发现,数字
i
i
出现的次数就是。
那么就枚举
n
n
的约数,求出和
φni
φ
n
i
,计算答案即可。
时间复杂度:约
O(n−−√)
O
(
n
)
代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
long long ans,sum,n,a;
long long phi(long long x) //求phi[i]
{
ans=x;
for (long long i=2;i*i<=x;i++)
if (!(x%i))
{
ans=ans/i*(i-1);
while (!(x%i)) x/=i;
}
if (x>1) ans=ans/x*(x-1);
return ans;
}
int main()
{
fre(beats);
scanf("%lld",&n);
for (long long i=1;i*i<=n;i++) //枚举约数
if (!(n%i))
{
sum+=i*phi(n/i);
if (i*i!=n) sum+=(n/i)*phi(i); //不是完全平方数
}
printf("%lld\n",sum+1);
return 0;
}