AGC005D 题解

传送门

如果一个排列 \(P\) 满足对于所有的 \(i\) 都有 \(|P_i-i|\neq k\),则称排列 \(P\) 为合法的。现给出 \(n\)\(k\),求有多少种合法的排列。

由于答案很大,请输出答案对 \(924844033\) 取模的结果。

\(2\leq n\leq 2\times 10^3\)\(1\leq k\leq n-1\)

一个新的trick:考虑一个 \(n\times n\) 的方格,要求选一些格子,每行每列恰好一个。如果第 \(i\) 行选了 \((i,j)\),表示 \(P_i=j\)

\(|P_i-i|\neq k\iff \text{第 i 行有至多两个位置不能选}\)

问题变成:给定 \(n\times n\) 的方格图,有一些格子不能选。求选若干个格子,每行每列恰好一个的方案数。

考虑容斥,总方案数显然是 \(n!\)

\(S_i\) 为 所有选了,第 \(i\) 个不能选的格子,的方案 的集合,则 \(ans=n!-|S_1\cup S_2\cup S_3\cup\cdots|\)

容斥一下。问题变成对于每个 \(k\),求 \(\sum_{\{i1\dots ik\}} |S_{i1}\cap S_{i2}\cap \cdots\cap S_{ik}|\)

单看 \(\sum\) 里面的,我们好像要单独求出每一种 \(k\) 个不能选的格子强制选的方案数。但这一整个 \(sum\) 可以一起算,即 “从不能选的格子里选 \(k\) 个,剩下随便选,满足每行每列一个” 的方案数,记这个问题为 ①。

\(f_i\) 表示“从不能选的格子里选 \(i\) 个满足每行每列最多 \(1\) 个”的方案数。

则 ① 的答案是 \(f_k\times (n-k)!\)。现在就是求 \(f_k\) 了。

如果把两个同行(或同列)的不能选的格子之间连边,发现构成了若干条“链”。每行每列最多 \(1\) 个的条件,等价于每条链上不能选相邻的。

如果只有一条链,是很经典的 DP:\(dp[i][j][0/1]\) 表示前 \(i\) 个结点选 \(j\) 个且第 \(i\) 个结点选/不选,满足相邻的不选 的方案数。

如果有多条链,可以用一个trick:在每条链的尾巴接一个结点,让这个结点接到下一条链的开头,同时强制规定这个结点不选

posted @ 2024-02-26 22:22  FLY_lai  阅读(10)  评论(0编辑  收藏  举报