1 条题解

  • 0
    @ 2025-12-10 17:40:34

    题意简化

    给定 nn 个数 k1,k2,...,knk_1, k_2, ..., k_n,求:

    LCM(f(k1),f(k2),...,f(kn))mod109+7LCM(f(k_1), f(k_2), ..., f(k_n)) \bmod 10^9+7

    其中 f(i)f(i) 是斐波那契数列:f(0)=0,f(1)=1,f(i)=f(i1)+f(i2)f(0)=0, f(1)=1, f(i)=f(i-1)+f(i-2)

    n5×104n \le 5\times 10^4ki106k_i \le 10^6

    核心思想:数论性质 + 容斥

    1. 斐波那契数列的性质

    关键性质:

    • gcd(f(a),f(b))=f(gcd(a,b))\gcd(f(a), f(b)) = f(\gcd(a, b))
    • 由这个性质可以推导出 LCM 的表达式

    2. LCM 公式推导

    对于数列 f(k1),f(k2),...,f(kn)f(k_1), f(k_2), ..., f(k_n),有:

    $$LCM(f(k_1), f(k_2), ..., f(k_n)) = \prod_{d=1}^{\max(k_i)} f(d)^{c_d} $$

    其中指数 cdc_d 由包含因子 ddkik_i 决定。

    更具体地,利用莫比乌斯反演:

    f(n)=dng(d)f(n) = \prod_{d|n} g(d)

    其中 g(d)g(d) 是某个函数。

    反过来:

    g(n)=dnf(d)μ(n/d)g(n) = \prod_{d|n} f(d)^{\mu(n/d)}

    3. 代码算法解析

    预处理部分:

    1. 线性筛:计算莫比乌斯函数 μ(i)\mu(i)
    2. 斐波那契数列:计算 f(i)f(i)109+710^9+7
    3. 计算 g(i)g(i):使用公式 g(n)=dnf(d)μ(n/d)g(n) = \prod_{d|n} f(d)^{\mu(n/d)}

    代码实现巧妙:

    // 初始化 g[i] = f[i]
    for (int i = 1; i <= n; i++) g[i] = f[i];
    
    // 通过除法计算 g
    for (int i = 1; i <= n; i++) {
        int t = qpow(g[i], mod-2);  // g[i] 的逆元
        for (int j = i+i; j <= n; j += i)
            g[j] = g[j] * t % mod;
    }
    

    这等价于:g[j]=djf(d)μ(j/d)g[j] = \prod_{d|j} f(d)^{\mu(j/d)}

    主计算部分:

    1. 读入 kik_i,标记 p[k_i] = true
    2. 对于每个 ii,检查是否存在 kjk_jii 的倍数
    3. 如果存在,则将 g[i]g[i] 乘入答案

    为什么这样正确?

    • g(i)g(i) 表示斐波那契数 ff 的某种"本原"因子
    • 如果存在 kjk_jii 的倍数,那么 f(i)f(i) 会"贡献"到 f(kj)f(k_j) 的质因子分解中
    • 求 LCM 时需要包含所有 g(i)g(i),其中 ii 能整除至少一个 kjk_j

    算法步骤

    1. 预处理(到 10610^6):

      • 线性筛 μ(i)\mu(i)
      • 计算 f(i)f(i)modmod
      • 计算 g(i)=dif(d)μ(i/d)g(i) = \prod_{d|i} f(d)^{\mu(i/d)}
    2. 读入处理

      • 记录最大的 kik_imxmx
      • 标记哪些 kk 值出现过
    3. 计算答案

      ans = 1
      for i = 1 to mx:
          flag = false
          for j = i; j <= mx; j += i:
              if p[j]:
                  flag = true
                  break
          if flag:
              ans = ans * g[i] % mod
      

    复杂度分析

    • 预处理:O(MlogM)O(M \log M)M=106M=10^6
    • 标记 kik_iO(n)O(n)
    • 计算答案:每个 ii 检查倍数,总复杂度 O(MlogM)O(M \log M)
    • 可过 M=106M=10^6

    关键点

    1. 数论公式

    $$LCM(f(k_1),...,f(k_n)) = \prod_{d} g(d)^{[\exists k_i \text{是} d \text{的倍数}]} $$

    2. gg 的计算

    ggff 的莫比乌斯反演,表示"本原"因子。

    3. 倍数检查

    只需检查是否存在 kik_idd 的倍数,不需要统计个数。

    样例解释

    输入:k=[1,3,9,6]k = [1, 3, 9, 6]

    斐波那契值:

    • f(1)=1f(1)=1
    • f(3)=2f(3)=2
    • f(6)=8f(6)=8
    • f(9)=34f(9)=34

    LCM = LCM(1,2,8,34) = 136

    代码特点

    • 预处理到 10610^6(最大 kik_i
    • 使用莫比乌斯反演
    • 逆元优化 gg 的计算
    • 倍数标记检查
    • 1

    信息

    ID
    6024
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者