[SDOi2012]Longge的问题 (数论)
题目
题目背景
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_x\sum_{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);
}