容斥 dp

容斥系数一般是 ( − 1 ) ∣ S ∣ (-1)^{|S|} (1)S

初学容斥原理时都做过这样的一道题。有一张 n × m n \times m n×m 的棋盘,在上面染色,要求任意一行、任意一列的颜色都不完全相同。这是一个模型

全部 − - 至少一个 + + + 至少两个 − ⋯ = - \cdots = =一个也没有。

所以我们枚举一下有多少行颜色一定相同,有多少列颜色一定相同。可以发现如果只有行或只有列,那么每行(每列)的颜色不一定相同,而同时有行和列就必须是同一颜色。那么用行数 + + + 列数套上容斥系数就行了。

其实在这道题中,我们容易得到有至少 i i i 行相同且有至少 j j j 列相同的方案数,当我们不容易得到时,就需要使用容斥 dp 了

容斥的一些模型如下

  1. 所有的情况 − - 至少有一个 + + + 至少有两个 − ⋯ = - \cdots = =一个也没有。
  2. 全部都有 − - 一个也没有 = = = 至少有一个
  3. 至少有 k k k − - ( k + 1 k ) k + 1 \choose k (kk+1) × \times ×至少有 k + 1 k+1 k+1 + + + ( k + 2 k ) k + 2 \choose k (kk+2) × \times × 至少有 k + 2 k+2 k+2 ⋯ = \cdots = = 恰好有 k k k 个的方案数
  4. 补集转化
  5. min-max 容斥

然后随便做几道题熟悉一下。

BZOJ 3622 (type 3)

给定两个全不相等的两个序列 a a a b b b,把 a a a 中的元素和 b b b 中的元素两两配对,求 a i > b j a_i > b_j ai>bj a i < b j a_i < b_j ai<bj 的配对数恰好多 k k k 的方案数。

显然所有的配对不是 a i > b j a_i > b_j ai>bj 就是 a i < b j a_i < b_j ai<bj,解一个方程可以转换成了恰好有 x x x 个配对满足 a i > b j a_i > b_j ai>bj 的方案数。

可以考虑一下第三类容斥,把问题转换成求有至少 x , x + 1 , . . . , n x, x + 1,...,n x,x+1,...,n 个配对满足 a i > b j a_i > b_j ai>bj 的方案数。

a a a b b b 从小到大排序,设 f i , j f_{i,j} fi,j a 1 ∼ a i a_1 \sim a_i a1ai 配对了 j j j 个满足要求的 b j b_j bj,其它不管的方案数,其实这是一个延迟转移。

f i , j = f i − 1 , j + f i − 1 , j − 1 × ( k − j + 1 ) f_{i,j} = f_{i - 1, j} + f_{i-1,j-1} \times (k - j + 1) fi,j=fi1,j+fi1,j1×(kj+1)

其中 k k k 是最大的数,满足 k < a i k < a_i k<ai

那么 f n , x ( n − x ) ! f_{n,x} (n-x)! fn,x(nx)! 即为至少有 j j j 个的方案数。

a n s = ∑ i = x n ( x i ) f n , i ( n − i ) ! ans = \sum_{i = x}^n {x \choose i} f_{n,i} (n-i)! ans=i=xn(ix)fn,i(ni)!

ARC 115 E (type 1)

n n n 个位置,每个位置上的数字不能大于 a i a_i ai,求相邻的数都不相同的序列有多少个。

1 ≤ n ≤ 5 × 1 0 5 , 1 ≤ a i ≤ 1 0 9 1 \leq n \leq 5 \times 10^5, 1 \leq a_i \leq 10^9 1n5×105,1ai109

所有的情况 − - 至少有一个 + + + 至少有两个 − ⋯ = - \cdots = =一个也没有。

f i , j f_{i,j} fi,j 为将前 i i i 个元素分成 j j j 段的方案数,其中每段内都相等,段与段之间无所谓。那么答案是 f n , n − f n , n − 1 + f n , n − 2 ⋯ f_{n,n} - f_{n,n-1} + f_{n,n-2} \cdots fn,nfn,n1+fn,n2

f i , j = ∑ k < i f k , j − 1 × min ⁡ k + 1 ≤ i a k f_{i,j} = \sum_{k <i} f_{k,j-1} \times \min_{k+1 \leq i} a_k fi,j=k<ifk,j1×k+1iminak

但显然这个转移是 O ( n 2 ) O(n^2) O(n2),但容斥系数只与 j j j 的奇偶性有关,所以状态可以改成 f i , 0 / 1 f_{i,0/1} fi,0/1 表示前 i i i 个数分成偶数段(奇数段)的方案数。

f i , 1 = ∑ k < i f k , 0 × min ⁡ k + 1 ≤ i a k f i , 0 = ∑ k < i f k , 1 × min ⁡ k + 1 ≤ i a k f_{i,1} = \sum_{k <i}f_{k,0} \times \min_{k + 1 \leq i} a_k \\ f_{i,0} = \sum_{k <i} f_{k,1} \times \min_{k+1 \leq i} a_k fi,1=k<ifk,0×k+1iminakfi,0=k<ifk,1×k+1iminak

好像这个转移还是 O ( n 2 ) O(n^2) O(n2),但是可以优化了。我们用单调栈算出每个 a k a_k ak 作为最小值的区间,然后再维护一个 dp 的前缀和,加上一点点细节就可以了。

posted @ 2021-07-19 16:12  ylxmf2005  阅读(257)  评论(0)    收藏  举报