一、题意
求解\(1\sim n\)与\(n\)不互质的数的和。
二、欧拉函数解法
定义:欧拉函数是小于\(n\)的数中与\(n\)互质的数的数目。
例如\(φ(8)=4\),因为\(1,3,5,7\)均和\(8\)互质。
\(sum(n)=\phi(1)+\phi(2)+\phi(3)+...+\phi(n-1)+\phi(n)\)
利用欧拉函数即可求解,\(1 \sim n\)比\(n\)小且与\(n\)互素的数的总和为\(sum(n) = n * phi(n) / 2\);
那么可以先求出\(1\sim n-1\)的总和,然后减去\(sum(n)\)即可。
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
const ULL mod = 1000000007;
ULL euler(ULL n) {
ULL res = n, a = n;
for (ULL i = 2; i * i <= a; i++) {
if (a % i == 0) {
res = res / i * (i - 1);
while (a % i == 0) a /= i;
}
}
if (a > 1) res = res / a * (a - 1);
return res;
}
int main() {
ULL n;
while (~scanf("%llu", &n), n) {
ULL sum = n * (1 + n) / 2 - n, ans;
ans = sum - euler(n) * n / 2;
printf("%llu\n", ans % mod);
}
return 0;
}
三、分解质因数+容斥原理
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1000000007;
int main() {
LL n, m;
while (cin >> m && m) {
if (m == 1) {
cout << "0" << endl;
continue;
}
n = m;
//分解质因数
vector<LL> p;
for (LL i = 2; i * i <= n; i++) {
if (n % i == 0) {
p.push_back(i);
while (n % i == 0)
n = n / i;
}
}
if (n > 1) p.push_back(n);
LL ans = 0;
for (int i = 1; i < (1 << p.size()); i++) {
int cnt = 0;
int t = 1;
for (int j = 0; j < p.size(); j++) {
if (i >> j & 1) {
cnt++;
t *= p[j];
}
}
LL num = (m - 1) / t;
LL tmp = (t + t * num) * num / 2;
if (cnt & 1)
ans += tmp;
else
ans -= tmp;
}
cout << ans % mod << endl;
}
return 0;
}