Luogu

算法

  • 数学(素数筛,因子个数)

思路

对于原式做如下推导:

1x+1y=1n!x+yxy=1n!n!(x+y)=xyn!x+n!yxy=0xyn!xn!y=0\large \begin{aligned} \frac{1}{x} + \frac{1}{y} &= \frac{1}{n!} \\ \frac{x + y}{xy} &= \frac{1}{n!} \\ n! \cdot (x + y) &= xy \\ n! \cdot x + n! \cdot y - xy &= 0 \\ xy - n! \cdot x - n! \cdot y &= 0 \end{aligned}

由上式联想到:

(ax)(bx)abaxbxX2\large (a - x) (b - x) \to ab - ax - bx - X^2

比较两式,发现缺少 (n!)2(n!)^2 项。加上 (n!)2(n!)^2,得:

(xn!)(yn!)=(n!)2\large \begin{aligned} (x - n!)(y - n!) = (n!)^2 \end{aligned}

由于等式左边是乘积的形式,所以 (xn!)(x - n!)(yn!)(y - n!) 必定是 (n!)2(n!)^2 的一对因子。
nn 质因数分解:

n=i=0kpiαi\large n = \prod_{i = 0}^{k} p_i^{\alpha_{i}}

对于 n!n! 的因子个数 sum1sum_{1} 有:

sum1=i=0k(αi+1)sum_{1} = \prod_{i=0}^{k} (\alpha_{i}+ 1)

(n!)2(n!)^2 的因子个数 sum2sum_{2} 为:

sum2=i=0k(α12+1)sum_{2} = \prod_{i = 0}^{k} (\alpha_{1} \cdot 2 + 1)

根据乘法原理,最后的答案为所有 sum2sum_{2} 的乘积。

代码

#include <bits/stdc++.h>

using namespace std;

constexpr int MOD = 1e9 + 7;

inline vector<int> GetPrimes(int Limit) {
vector<int> primes;
vector<bool> mark(Limit + 1);

for (int i = 2; i <= Limit; i ++) {
if (mark[i] == false) {
primes.emplace_back(i);
}

for (int j = 0; i * primes[j] <= Limit; j ++) {
mark[i * primes[j]] = true;
if (i % primes[j] == 0) {
break;
}
}
}

return primes;
}

int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

int n;
cin >> n;

vector<int> primes = GetPrimes(n);
// * 注意由于是连乘,所以 answer 的初始值为 1.
long long answer = 1;

for (auto&& p : primes) {
int alpha = 0, number = n;

while (number) {
alpha += number / p;
number /= p;
}

answer = (answer * (alpha + alpha + 1) % MOD) % MOD;
}

cout << answer % MOD << '\n';

return 0;
}