Files
python/TangDou/AcWing_TiGao/T5/RongChi/HDU3501_1.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

64 lines
2.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int mod = 1000000007;
signed main() {
int m;
while (cin >> m && m) {
if (m == 1) {
cout << "0" << endl;
// 边界需要特别注意!本题的左边界是1
// 表示的含义是小于1,并且与1不互质的数的加法和,当然是0。
// 在做题时,先想正常思路,然后再思考一下边界是不是用特判。
continue;
}
int n = m; // 复制出来进行质因数分解
// 分解质因数
vector<int> p;
for (int 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);
// 容斥原理
int s = 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];
}
}
/* t:质因子的累乘积
cnt:质因子的个数
举栗子:
枚举到的组合中只有数字2,那么2,4,6,8,10,....需要加上
枚举到的组合中只有数字3,那么3,6,9,12,15,....需要加上
枚举到的组合中中6.有数字2,3,那么6,12,18,....需要减去
*/
int num = (m - 1) / t; // 题目要求:比m小的数字中,也就是[1~m-1]这些数字中有多少个数是t的倍数呢?是(m-1)/t个。
/* 这些数字,首个是t,第二个是t*2,最后一个是t*num
等差数列求和公式:(首项+末项)*项数/2
模板题是计数,这里不是计数,而是计算这些数加在一起是多少,不能傻傻的一个个累加,而是采用了数学中的等差数列求和公式,
否则聪明的高斯该生气了~
*/
int tmp = (t + t * num) * num / 2;
if (cnt & 1) // 奇数的加
s += tmp;
else // 偶数的减
s -= tmp;
}
cout << s % mod << endl; // 取模输出
}
}