419 小U的数列因子挑战| 豆包MarsCode AI刷题

108 阅读3分钟

问题描述

小U得到一个数列,数列的定义如下:

  1. 初始条件为 f(1) = af(2) = b
  2. 对于第 i 项,数列满足递推关系:f(i) = f(i-1) * f(i-2) * c^d

你需要计算出数列的第 n 项的因子数量。由于答案可能很大,请对 10^9 + 7 取模。


测试样例

样例1:

输入:a = 1, b = 2, c = 3, d = 4, n = 3
输出:10

样例2:

输入:a = 2, b = 3, c = 5, d = 2, n = 4
输出:30

样例3:

输入:a = 1, b = 1, c = 2, d = 1, n = 5
输出:5

解题思路

直接递推计算 f(i) 显然行不通,因为数列增长非常快,甚至第 4 项就可能超过 Python 的整数处理极限。因此,我们需要寻找一个更高效的方案来解决问题。

问题的核心是 如何计算一个数的因子数量

因子数量公式

如果一个数 x 的质因子分解为:

x=p1^e1 * p2^e2...* pk^ek

则 x 的因子数量可以表示为:

因子数量=(e1+1)×(e2+1)×⋯×(ek+1)

因此,计算 f(n)的因子数量只需要知道它的质因子分解

递推式分析

根据题意:

f(i)=f(i−1)×f(i−2)×c^d

  • 质因子累积:f(i)的质因子来源于 f(i−1)、f(i−2) 和 c^d 的质因子。
  • 我们只需要存储每一项的质因子及其指数,而不是存储实际的数值。

算法实现

  1. 质因子分解: 使用试除法将一个数分解为质因子及其指数。例如,分解 12得到 {2:2,3:1}。
  2. 合并质因子: 递推计算时,将两个数的质因子指数相加。例如,合并 {2:2,3:1} 和 {2:1,5:1} 得到 {2:3,3:1,5:1}。
  3. 因子数量计算: 根据质因子指数计算因子数量,并在每次操作中对 10^9 + 7 取模。
  4. 递归迭代: 通过存储 f(1) 和 f(2) 的质因子信息,利用递推关系不断更新到 f(n)。

代码实现

def solution(a: int, b: int, c: int, d: int, n: int) -> int:
    MOD = 10**9 + 7

    def prime_factorization(x):
        factors = {}
        d = 2
        while d * d <= x:
            while x % d == 0:
                factors[d] = factors.get(d, 0) + 1
                x //= d
            d += 1
        if x > 1:
            factors[x] = factors.get(x, 0) + 1
        return factors

    def multiply_factors(f1, f2):
        result = f1.copy()
        for p, exp in f2.items():
            result[p] = result.get(p, 0) + exp
        return result

    def count_factors(factors):
        result = 1
        for exp in factors.values():
            result = result * (exp + 1) % MOD
        return result

    if n == 1:
        return count_factors(prime_factorization(a))
    if n == 2:
        return count_factors(prime_factorization(b))
    
    f1 = prime_factorization(a)
    f2 = prime_factorization(b)
    c_power_d = prime_factorization(c**d)

    for _ in range(3, n + 1):
        f_next = multiply_factors(multiply_factors(f1, f2), c_power_d)
        f1, f2 = f2, f_next
    
    return count_factors(f2)

if __name__ == '__main__':
    print(solution(1, 2, 3, 4, 3) == 10)
    print(solution(2, 3, 5, 2, 4) == 30)
    print(solution(1, 1, 2, 1, 5) == 5)

代码解析

核心函数

  1. prime_factorization(x)

    • 使用试除法分解数 xxx 的质因子。
    • 输出字典表示质因子及其对应的指数。
  2. multiply_factors(f1, f2)

    • 合并两个质因子字典,将相同质因子的指数相加。
  3. count_factors(factors)

    • 根据质因子指数计算因子数量,并对 MODMODMOD 取模。
  4. 主函数 solve

    • 初始化 f(1)f(1)f(1) 和 f(2)f(2)f(2) 的质因子。
    • 根据递推公式计算质因子,最终得到第 nnn 项的因子数量。

复杂度分析

  1. 时间复杂度

    • 质因子分解:单次复杂度为 O(根号x)。
    • 递推计算:进行 n−2次递推,每次操作处理质因子指数,因此总体复杂度为 O(n×根号c^d)。
  2. 空间复杂度

    • 使用字典存储质因子,空间复杂度与质因子数量成正比。

总结

通过将递推问题转化为质因子分解问题,我们避免了直接计算大数值,从而大大降低了计算复杂度。