题目-樱花

在这里插入图片描述

问题分析

对原式进行变形
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 xn!+yn!=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=xn!xn!

x ∈ Z + x \in Z ^ + xZ+, 求 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=xn!(xn!+n!)n!=n!+xn!n!2

因为 n ! n! n!是正整数, 不需要考虑

又因为
1 y = 1 n ! − 1 x \frac{1}{y} = \frac{1}{n!} - \frac{1}{x} y1=n!1x1

问题变成了 x x x如何取值, 使得 ( x − n ! ) ∣ n ! 2 (x - n!) | n! ^ 2 (xn!)n!2, 并且

x > n ! x > n! x>n!, 否则 y y y就是负数, 是矛盾的

因为分母 x − n ! x - n! xn!一定是正数, 满足条件的 x x x的个数等价于满足条件的 x − n ! x - n! xn!的个数, 也就等于了 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 pmn, m ≤ log ⁡ n m \le \log n mlogn
因此算法时间复杂度 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;
}