龙哥的问题

龙哥的问题
这题要求我们求出1~n之间的所有数与n的gcd之和。
我们知道如果两个数互质的话,两个数的gcd就是1,所以res =  gcd(1~n, n) = 互质的数 + gcd(不互质的数,n);
而对于两个不互质的我们有gcd(a, n) = gcd,而当我们两边同时除以gcd时我们有gcd(a % gcd, n % gcd) = 1;由此我们可以知道所有不与n互质的数的gcd都可以转换为gcd乘以与n % gcd互质的个数。
所以我们的答案就变成了res = gcd(a, n) + gcd(b % gcd, n % gcd) * gcd, (a与n互质,b与n不互质)。
代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 100010, M = 1e9;
int n;
LL get_euler(int n) 
{
    LL res = n;
    for (int i = 2; i <= n / i; i ++ ) 
        if (n % i == 0) 
        {
            while (n % i == 0) n /= i;
            res = res / i * (i - 1);
        }
    if (n > 1) res = res / n * (n - 1);
    return res;
}
int main() 
{
    int n;
    cin >> n;
    LL res = 0;
    for (int i = 1; i <= n / i; i ++ ) 
        if (n % i == 0) 
        {
            int t = n / i;
            res += get_euler(t) * i;
            if (i != t) res += get_euler(i) * t;
        }
    cout << res << endl;
    return 0;
}

 
                
             
         浙公网安备 33010602011771号
浙公网安备 33010602011771号