You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#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; // 取模输出
|
|
|
|
|
}
|
|
|
|
|
}
|