根据大佬的分析,我们设计提示词.
算这么个式子:
f是无平方因子数的个数
prompt
上下文紧跟193题.1
2
3
4
5
6
7这是另一道题,但是计算方式和上面的题差不多.
我们令上题中 $f(i)=\sum_{i=1}^{\lfloor\sqrt{N}\rfloor}
\left\lfloor\dfrac{N}{i^2}\right\rfloor\cdot \mu(i)$ ,然后再令 $S(N)=\sum_{i=1}^{\lfloor\sqrt{N}\rfloor}
i^2\cdot
f\left(\left\lfloor\dfrac{N}{i^2}\right\rfloor\right)$ .这道题的N是10^{14},你仍然可以直接枚举S(N)的i,在O(\sqrt n\log n)的时间内算出答案.
参考上面的代码解决该题.
gemini
1 | 好的,这道题的 $N = 10^{14}$,所以 $\lfloor\sqrt{N}\rfloor = 10^7$。 |
阶么奈犯了一个很蠢的错误,就是把10^14打成10^16,然后就RE了.
忘了提示取模,这是Flu的锅,手修一下就过了.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// N = 10^14, sqrt(N) = 10^7 = 10,000,000
const int MAX_SIEVE_N = 10000000 + 10;
// 10^7 内的质数数量约为 664,579
const int MAX_PRIMES = 670000;
// 全局数组自动初始化为0
int vis[MAX_SIEVE_N]; // 存最小质因数,负的表示质数表中的位置(负的)
int p[MAX_PRIMES], ptop = 0; // 存质数
short mu[MAX_SIEVE_N]; // 莫比乌斯函数
/**
* @brief 欧拉筛法计算莫比乌斯函数
* @param n 筛法上限 [1, n]
*/
void sieve(int n) {
mu[1] = 1;
for (int i = 2; i <= n; ++i) {
if (!vis[i]) {
vis[i] = -(++ptop);
p[ptop] = i;
mu[i] = -1; // 质数的mu为-1
}
for (int j = 1; j <= ptop; ++j) {
// 使用 long long 防止 i * p[j] 中间计算溢出
long long product = (long long)i * p[j];
if (product > n) {
break;
}
vis[product] = p[j];
if (i % p[j] == 0) {
// mu[product] 默认为 0
break;
} else {
mu[product] = -mu[i];
}
}
}
}
int main() {
// 定义 N = 10^14
long long N_VALUE = 100000000000000LL;
// 定义 N 的平方根 S_outer = 10^7
const int S_OUTER = 10000000;
const int mod=1e9+7;
// 1. 运行筛法,预处理 1 到 10^7 的 mu 函数
sieve(S_OUTER);
long long total_S = 0;
// 2. 外层循环 i, 计算 S(N)
// i 必须是 long long, 因为 i*i 会超过 int
for (long long i = 1; i <= S_OUTER; ++i) {
// M = floor(N / i^2)
long long M = N_VALUE / (i * i);
// 计算 f(M)
// f(M) = sum_{k=1}^{sqrt(M)} [M/k^2] * mu(k)
// S_inner = floor(sqrt(M))
long long S_inner = (long long)sqrt(M);
long long f_M = 0;
// 3. 内层循环 k, 计算 f(M)
// k 必须是 long long, 因为 k*k 会超过 int
for (long long k = 1; k <= S_inner; ++k) {
// k 最大为 S_OUTER (当 i=1),
// 此时 mu[k] 都在预处理范围内
f_M += (M / (k * k)) * mu[k]%mod;
f_M%=mod;
}
// 4. 累加 S(N)
total_S += (i * i)%mod * f_M%mod;
total_S%=mod;
}
// 5. 输出最终答案
std::cout << total_S << std::endl;
return 0;
}