1 条题解

  • 0
    @ 2025-10-21 22:14:07

    题意理解

    给定 n×nn \times n00-11 矩阵 cc,求满足以下条件的 00-11 序列对 (a,b)(a, b) 的数量:

    $$c_{i,j} = a_i \ \text{或} \ c_{i,j} = b_j \quad \text{对所有 } i,j \in [1,n] $$

    其中"或"是逻辑或运算。

    核心思路

    关键观察

    1:约束条件的等价形式

    条件 ci,j=ai 或 ci,j=bjc_{i,j} = a_i \ \text{或} \ c_{i,j} = b_j 等价于:

    • 如果 ci,j=0c_{i,j} = 0,那么必须有 ai=0a_i = 0bj=0b_j = 0
    • 如果 ci,j=1c_{i,j} = 1,那么 aia_ibjb_j 至少有一个为 11

    2:矩阵的块结构

    考虑将矩阵按 aia_ibjb_j 的值划分:

    • I0={iai=0}I_0 = \{i \mid a_i = 0\}, I1={iai=1}I_1 = \{i \mid a_i = 1\}
    • J0={jbj=0}J_0 = \{j \mid b_j = 0\}, J1={jbj=1}J_1 = \{j \mid b_j = 1\}

    那么约束条件转化为:

    • 对于 iI0,jJ0i \in I_0, j \in J_0:必须有 ci,j=0c_{i,j} = 0
    • 对于其他情况:ci,jc_{i,j} 可以是 0011

    3:容斥原理的应用

    我们可以枚举 I0I_0J0J_0 的大小和位置,但直接枚举不可行。更好的方法是使用容斥原理

    f(S)f(S) 表示至少有集合 SS 中的位置违反约束的方案数,那么由容斥原理:

    $$\text{答案} = \sum_{S \subseteq \text{所有可能违反的位置}} (-1)^{|S|} \cdot f(S) $$

    算法框架

    方法一:基于行的容斥

    考虑对行进行容斥。设 dp[i][mask]dp[i][mask] 表示处理了前 ii 行,当前行的某种状态为 maskmask 时的方案数。

    状态设计

    • 记录每列 bjb_j 的取值约束
    • 记录当前行的 aia_i 取值对后续的影响

    状态转移

    • 枚举当前行 aia_i 的取值 (0011)
    • 根据 ci,c_{i,\ast} 更新列的约束条件
    • 转移到下一状态

    方法二:二分图建模

    将问题建模为二分图:

    • 左部 nn 个点对应 a1,,ana_1, \dots, a_n
    • 右部 nn 个点对应 b1,,bnb_1, \dots, b_n
    • (i,j)(i,j) 的约束条件对应二分图的某种结构

    然后使用图论计数的方法求解。

    方法三:生成函数

    使用生成函数来编码约束条件。对于每个位置 (i,j)(i,j),约束条件可以写为:

    [ci,j=0](1ai)(1bj)=1[c_{i,j} = 0] \Rightarrow (1-a_i)(1-b_j) = 1 [ci,j=1]1(1ai)(1bj)=1[c_{i,j} = 1] \Rightarrow 1 - (1-a_i)(1-b_j) = 1

    然后使用多元生成函数容斥原理计算。

    关键公式

    容斥公式

    R[n]R \subseteq [n] 是行的一个子集,C[n]C \subseteq [n] 是列的一个子集,定义:

    $$f(R,C) = \prod_{i \in R} [\text{第 } i \text{ 行的约束}] \times \prod_{j \in C} [\text{第 } j \text{ 列的约束}] $$

    那么答案可以表示为:

    $$\text{答案} = \sum_{R,C} (-1)^{|R|+|C|} \cdot g(R,C) $$

    其中 g(R,C)g(R,C) 是考虑额外约束后的方案数。

    DP 状态转移

    dp[i][mask]dp[i][mask] 表示前 ii 行的状态,其中 maskmask 编码了列的约束信息:

    $$dp[i][mask'] = \sum_{mask} dp[i-1][mask] \cdot \text{transfer}(mask, mask', i) $$

    复杂度分析

    • 朴素容斥O(22n)O(2^{2n}) 不可行
    • 优化DPO(n2n)O(n \cdot 2^n) 对于 n20n \leq 20 可行
    • 进一步优化:利用问题的特殊结构达到 O(n2)O(n^2)O(n3)O(n^3)

    实现要点

    1. 模运算:所有运算在模 998244353998244353 下进行
    2. 状态压缩:对于较小的 nn 可以使用位运算优化
    3. 预处理:预处理矩阵的某些特征以加速计算
    4. 对称性:利用问题的对称性减少状态数

    总结

    本题的核心在于将逻辑约束转化为组合计数问题,并通过容斥原理动态规划求解。关键技巧包括:

    1. 约束分析:理解 ci,j=ai 或 ci,j=bjc_{i,j} = a_i \ \text{或} \ c_{i,j} = b_j 的组合含义
    2. 容斥转化:将"满足所有约束"转化为"不违反任何约束"
    3. 状态设计:设计高效的DP状态来记录约束信息

    这是一个典型的组合计数+约束满足难题,需要深厚的组合数学功底和算法设计能力。

    • 1

    「2021 集训队互测」这是一道集训队胡策题

    信息

    ID
    3667
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    5
    已通过
    1
    上传者