题目
题目背景
SDOi2012
题目描述
Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出
[sum_{i=1}^{n}GCD(i,n)
]
输入输出格式
输入格式:
一个整数,为N。
输出格式:
一个整数,为所求的答案。
输入输出样例
输入样例#1: 复制
6
输出样例#1: 复制
15
说明
对于60%的数据,(0<N<=2^{16})
对于100%的数据,(0<N<=2^{32})
题解
显然直接枚举会超时.
但有60分可得.
考虑换个枚举点.
可能成为GCD(i,n)的数就是n的因子.
(sqrt n)的枚举n的因子.
然后求
(sum_xsum_{i=1}^nGCD(i,n)== x)
前半部枚举,考虑如何处理后半部分.
[sum_{i=1}^{n} GCD(i,n)==x
]
[sum_{i=1}^{n/x} GCD(i,n/x) == 1
]
看出这就是求(phi {x})
然后直接求就好.
时间复杂度:(O(因子个数*sqrt n))
CODE:
// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <cmath>
#define ll long long
ll phi(ll x)
{
ll ans = x,qwq = sqrt(x);
for(ll i = 2;i <= qwq;++i)
if(x % i == 0)
{
ans = ans - ans / i;
while(x % i == 0) x /= i;
}
if(x > 1) ans = ans - ans / x;
return ans;
}
int main() {
ll n;
scanf("%lld",&n);
ll m = sqrt(n);
ll ans = 0;
for(int i = 1;i <= m;++ i) {
if(n % i == 0) ans += i * phi(n / i) + n / i * phi(i);
}
if(m * m == n) ans -= m * phi(m);
printf("%lld",ans);
}