1 条题解

  • 0
    @ 2025-10-28 10:33:41

    问题重述

    nn 张卡牌,每张卡牌有一个数字 sis_i。进行 mm 轮游戏,每轮给出 cic_i 个质数,要求计算选择卡牌子集的方案数,使得所选卡牌的数字乘积包含所有给出的质因子。


    关键观察

    1. 值域限制的重要性

    • si2000s_i \le 2000pi,j2000p_{i,j} \le 2000
    • 2000 以内的质数只有约 303
    • 这是解题的关键突破口

    2. 问题转化

    对于一轮游戏,设给出的质数集合为 PP。我们需要计算:

    $$\sum_{S \subseteq [n]} [\forall p \in P, p \mid \prod_{i \in S} s_i] $$

    等价于:对于每个 pPp \in P,至少选择一张包含质因子 pp 的卡牌。


    核心解法

    1. 质因数分解预处理

    对每个 sis_i 和每个质数 p2000p \le 2000,预处理:

    • sis_i 包含哪些质因子
    • 对于每个质数 pp,有哪些卡牌包含它

    2. 容斥原理

    ApA_p 表示「不选择任何包含质因子 pp 的卡牌」的坏事件。

    根据容斥原理:

    $$\text{答案} = \sum_{T \subseteq P} (-1)^{|T|} \times 2^{f(T)} $$

    其中 f(T)f(T) 表示「不包含 TT 中任何质因子的卡牌数量」。

    解释:我们枚举「缺少哪些质因子」的集合 TT,容斥计算。

    3. 状态压缩

    由于 ci18000\sum c_i \le 18000,但每轮的 cic_i 可能达到 10+,直接枚举子集不可行。

    优化思路:将质数编号为 0,1,,3020, 1, \dots, 302,用位掩码表示质数集合。


    算法框架

    1. 预处理阶段

    1. 筛出 2000 以内的所有质数,共 K303K \approx 303
    2. 对每个 sis_i,计算其质因数分解,得到位掩码 maskimask_i
    3. 对每个质数 pp,记录包含它的卡牌集合

    2. 对每轮游戏的处理

    设本轮质数集合为 PP,对应的位掩码为 MM

    关键优化:我们只关心与 MM 相关的质数,其他质数可以忽略。

    定义 g[T]g[T] 表示「质因子集合恰好为 TT 的卡牌数量」,其中 TMT \subseteq M

    那么:

    f(T)=TM=g[T]f(T) = \sum_{T' \cap M = \emptyset} g[T']

    即不包含 TT 中任何质因子的卡牌数量。

    3. 快速计算容斥

    使用 SOS DP(Sum Over Subsets)技术:

    F[T]F[T] 表示「质因子集合是 TT 的子集的卡牌数量」。

    那么:

    f(T)=F[]F[T]f(T) = F[\emptyset] - F[T]

    F[T]F[T] 可以通过高维前缀和(快速莫比乌斯变换)在 O(K2K)O(K \cdot 2^K) 时间内计算,但这里 K=MK = |M| 较小。

    4. 最终计算

    $$\text{答案} = \sum_{T \subseteq M} (-1)^{|T|} \times 2^{f(T)} $$

    复杂度分析

    1. 预处理

    • 质数筛:O(2000)O(2000)
    • 分解 nn 个数:$O(n \times \frac{2000}{\log 2000}) \approx O(10^6 \times 300)$

    2. 每轮游戏

    • k=cik = c_i,即本轮质数个数
    • 计算 FF 数组:O(k2k)O(k \cdot 2^k)
    • 容斥计算:O(2k)O(2^k)

    由于 ci18000\sum c_i \le 18000,且 2k2^k 增长很快,但实际中 kk 不会太大(否则 2k2^k 指数爆炸)。


    优化技巧

    1. 分组处理

    由于不同轮次的质数集合可能有重叠,可以:

    • 缓存已计算过的质数集合的结果
    • 对质数集合进行哈希

    2. 位运算优化

    • 使用 __builtin_popcount 快速计算集合大小
    • 使用位运算进行集合操作

    3. 模运算优化

    • 预处理 22 的幂次模 998244353998244353
    • 避免重复计算

    边界情况处理

    1. 无解情况

    如果存在某个质数 pPp \in P,没有卡牌包含它,那么答案直接为 00

    2. 空集情况

    根据题意,「什么都不选」是不合法的,因为要求乘积包含所有质因子。但我们的容斥公式中已经自然排除了这种情况。


    总结

    这道题的核心在于:

    1. 利用值域限制si2000s_i \le 2000 使得质数数量有限
    2. 容斥原理:将「必须包含」转化为「不能缺少」的容斥计算
    3. 状态压缩:用位运算高效表示和操作质数集合
    4. SOS DP:快速计算子集相关的和

    通过将原问题转化为质因子集合上的容斥计数,再利用位运算和动态规划进行优化,最终在可接受的时间内解决了这个看似复杂的问题。

    难度评估:这是一道结合了数论、组合数学和状态压缩的高难度题目,需要选手具备扎实的数学基础和算法优化能力。

    • 1