题解:洛谷 P2303 [SDOI2012] Longge 的问题

【题目来源】

洛谷:P2303 [SDOI2012] Longge 的问题 - 洛谷

【题目描述】

现在问题来了:给定一个整数 \(n\),你需要求出 \(\sum\limits_{i=1}^n \gcd(i, n)\),其中 \(\gcd(i, n)\) 表示 \(i\)\(n\) 的最大公因数。

【输入】

输入只有一行一个整数,表示 \(n\)

【输出】

输出一行一个整数表示答案。

【输入样例】

6

【输出样例】

15

【解题思路】

image

【算法标签】

《洛谷 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
posted @ 2026-02-20 20:15  团爸讲算法  阅读(0)  评论(0)    收藏  举报