题目-樱花

问题分析
对原式进行变形
x + y = x y n ! x + y = \frac{xy}{n!} x+y=n!xy
也就是
x ⋅ n ! + y ⋅ n ! = x y x\cdot n! + y \cdot n! = xy x⋅n!+y⋅n!=xy
只要 x x x固定 y y y也就固定了, 因此推导一下 x x x与 y y y之间的关系
y = x ⋅ n ! x − n ! y = \frac{x \cdot n!}{x - n!} y=x−n!x⋅n!
x ∈ Z + x \in Z ^ + x∈Z+, 求 y y y是正整数的方案数量
因为当前式子还是没办法直接计算, 继续对式子进行变形
y = ( x − n ! + n ! ) ⋅ n ! x − n ! = n ! + n ! 2 x − n ! y = \frac{(x - n! + n!) \cdot n!}{x - n!} = n! + \frac{n! ^ 2}{x - n!} y=x−n!(x−n!+n!)⋅n!=n!+x−n!n!2
因为 n ! n! n!是正整数, 不需要考虑
又因为
1 y = 1 n ! − 1 x \frac{1}{y} = \frac{1}{n!} - \frac{1}{x} y1=n!1−x1
问题变成了 x x x如何取值, 使得 ( x − n ! ) ∣ n ! 2 (x - n!) | n! ^ 2 (x−n!)∣n!2, 并且
x > n ! x > n! x>n!, 否则 y y y就是负数, 是矛盾的
因为分母 x − n ! x - n! x−n!一定是正数, 满足条件的 x x x的个数等价于满足条件的 x − n ! x - n! x−n!的个数, 也就等于了 n ! 2 n! ^ 2 n!2的约数个数
算法步骤
- 首先对 n ! n! n!进行分解质因数, 得到 n ! = p 1 k 1 p 2 k 2 . . . p k k n n! = p_1 ^ {k_1}p_2 ^ {k_2} ... p_k ^ {k_n} n!=p1k1p2k2...pkkn
- ( n ! ) 2 (n!) ^ 2 (n!)2的约数个数等于 ( 2 k 1 + 1 ) ( 2 k 2 + 1 ) . . . ( 2 k n + 1 ) (2k_1 + 1)(2k_2 + 1) ... (2k _n + 1) (2k1+1)(2k2+1)...(2kn+1)
对于每个指数 p p p, 计算的项数条件是 p m ≤ n p ^ m \le n pm≤n, m ≤ log n m \le \log n m≤logn
因此算法时间复杂度 O ( n log n ) O(n \log n) O(nlogn)
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10, MOD = 1e9 + 7;
int n;
int primes[N], cnt;
bool st[N];
void init(int k) {
for (int i = 2; i <= k; ++i) {
if (!st[i]) primes[cnt++] = i;
for (int j = 0; primes[j] <= k / i; ++j) {
st[i * primes[j]] = true;
if (i % primes[j] == 0) break;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
init(n);
LL ans = 1;
for (int i = 0; i < cnt; ++i) {
int p = primes[i];
LL cnt = 0;
for (int j = n; j; j /= p) cnt += j / p;
ans = ans * (2 * cnt % MOD + 1) % MOD;
}
cout << ans << '\n';
return 0;
}

京公网安备 11010502036488号