题解:洛谷 P2303 [SDOI2012] Longge 的问题
【题目来源】
洛谷:P2303 [SDOI2012] Longge 的问题 - 洛谷
【题目描述】
现在问题来了:给定一个整数 \(n\),你需要求出 \(\sum\limits_{i=1}^n \gcd(i, n)\),其中 \(\gcd(i, n)\) 表示 \(i\) 和 \(n\) 的最大公因数。
【输入】
输入只有一行一个整数,表示 \(n\)。
【输出】
输出一行一个整数表示答案。
【输入样例】
6
【输出样例】
15
【解题思路】

【算法标签】
《洛谷 P2303 Longge的问题》 #数学# #欧拉函数# #各省省选# #2012# #山东# #O2优化#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, ans; // n: 输入的正整数, ans: 计算结果
vector<int> ve; // 存储n的所有因子
// 计算欧拉函数phi(x):小于等于x且与x互质的正整数的个数
int phi(int x)
{
int res = x; // 初始化为x
// 分解质因数
for (int i = 2; i * i <= x; i ++ )
{
if (x % i == 0) // 如果i是x的质因数
{
res = res / i * (i - 1); // 根据欧拉函数公式:φ(n) = n * ∏(1 - 1/p)
while (x % i == 0) // 去除所有i因子
{
x /= i;
}
}
}
if (x > 1) // 如果还有剩余的质因数
{
res = res / x * (x - 1);
}
return res;
}
signed main()
{
cin >> n; // 输入正整数n
// 找出n的所有因子
for (int i = 1; i * i <= n; i++)
{
if (n % i == 0) // 如果i是n的因子
{
ve.push_back(i); // 添加因子i
if (i * i != n) // 避免重复添加平方根
{
ve.push_back(n / i); // 添加配对的因子n/i
}
}
}
// 计算:∑_{d|n} φ(n/d) * d
for (int i = 0; i < ve.size(); i++)
{
ans += phi(n / ve[i]) * ve[i];
}
cout << ans << endl;
return 0;
}
【运行结果】
6
15
浙公网安备 33010602011771号