1 条题解
-
0
题目重述
我们有一个颜色序列 ( a_1, a_2, \dots, a_n ),要计算满足以下条件的匹配(边的集合,无公共端点)的个数,模 ( 998244353 ):
- 每条边的两个端点颜色相同;
- 匹配中交叉边对的数量为偶数(两条边 ((u_1,v_1)) 与 ((u_2,v_2)) 交叉当且仅当 ( u_1 < u_2 < v_1 < v_2 ) 或 ( u_2 < u_1 < v_2 < v_1 ))。
样例分析 样例1 text n=3, a=[1,2,3] 颜色都不同,不能连边,只有空匹配 1 种。
样例2 text n=4, a=[1,2,1,2] 颜色1:位置1,3 颜色2:位置2,4
匹配:
空匹配 ✓
(1,3) ✓
(2,4) ✓
(1,3)+(2,4) ✗(交叉数为1,奇数)
答案 = 3
算法思路
题目其实是:对每个颜色,我们可以选一些不相邻的边(匹配),但不同颜色的边之间可能交叉,交叉总数必须是偶数。
第一步:不考虑交叉限制
对于颜色 (c),有 (m) 个位置,可以形成匹配的方案数 = 匹配数(即任意选若干条不相邻的边) = (F[m]),其中
(F[0]=1, F[1]=1, F[k] = F[k-1] + (k-1)F[k-2])
这是因为:要么不选第 (m) 个点((F[m-1])),要么选第 (m) 个点与前面某个点连边(有 (m-1) 种选择,剩下 (m-2) 个点方案数为 (F[m-2]))。所以不考虑交叉时,总方案 = (\prod_{c} F[|p_c|]),其中 (p_c) 是颜色 (c) 的位置列表。
第二步:考虑交叉限制
交叉只发生在不同颜色的边之间(因为同色边不可能交叉?不对,同色边可能交叉,比如颜色4的(1,3)和(2,4))。
但题目没有禁止同色边交叉,只是要求总交叉对数为偶数。我们可以把问题转化为:每个可能的边是一个变量 (x_e \in {0,1}) 表示选不选,约束是每个点最多关联一条边(匹配约束),并且
[ \sum_{e_1,e_2\ \text{cross}} x_{e_1} x_{e_2} \equiv 0 \pmod{2} ] 即交叉对的数量的奇偶性约束。这是一个二次型模2的计数问题。
代码分析
给出的代码正是用这个思路:
-
F数组:(F[k]) = 颜色有k个位置时,不考虑交叉约束的匹配数。
-
ans = (\prod F[|p_c|]) 是不考虑交叉约束的答案。
-
构建异或方程组:
- 对每对不同颜色的边,如果它们交叉,就在它们之间建立一个异或方程 (x_{e_1} \oplus x_{e_2} = 0)?不对,代码是用 bitset 表示二次型的矩阵。
- 实际上,代码是在构建一个图 (E),顶点是所有可能的边(按颜色分组编号),如果两条边交叉,就在它们之间连一条边(表示它们同时选会贡献1个交叉对)。
- 交叉对总数 mod 2 = (\sum_{e<f} E_{ef} x_e x_f)。
- 我们要计算满足这个二次型=0的向量 (x) 的个数(同时满足匹配约束?不,这里似乎没直接处理匹配约束,而是用另一种方法)。
-
高斯消元:
对矩阵 (E) 进行消元,计算它的秩 (r),那么满足 (x^T E x = 0) 的 (x) 的个数是 (2^{n-r})(在模2下)。 但这里 (E) 是对称的,模2下对角元可以非零。 -
ans2:就是满足交叉约束的匹配数(不考虑匹配约束?不对,这里 ans2 似乎是某种线性空间的大小)。 最终答案 = (ans + ans2) / 2,这可能是用容斥或者多项式方法的结果。
核心公式
最终答案 = (\frac{\text{所有匹配数} + \text{满足交叉偶数匹配数}}{2})
这是因为在某种变换下(比如添加一个虚拟变量),两者对称。
复杂度
- 构建 (E) 矩阵:最坏 (O(n^4))?但实际有优化,因为边数最多 (O(n^2)),所以构建是 (O(n^4)) 在 n=2000 不可行。
但代码中循环有 break 条件,可能平均情况可过。 - 高斯消元:(O(\text{边数}^3)) 也不行。但这里用的 bitset 优化,(O(\text{边数}^3 / 64)),边数最多约 (n^2/2),所以 (O(n^6/64)) 还是大,可能数据弱或实际边数少。
总结
这道题是一个带二次型模2约束的匹配计数问题,解法结合了:
- 匹配数公式
- 异或方程组求解
- 位运算优化
最终用 (总匹配数 + 合法匹配数)/2 得到答案。
- 1
信息
- ID
- 5479
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者