龙哥的问题
龙哥的问题
这题要求我们求出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;
}