龙哥的问题

image

龙哥的问题

这题要求我们求出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;
}
posted @ 2021-04-18 23:55  筱翼深凉  阅读(37)  评论(0编辑  收藏  举报