容斥原理qwq


update(2023.9.26) 增加例题 ABC321G
update(2023.10.10) 增加例题 ARC160D

感觉这篇博客讲的很清楚,下图截图自前面的博客,所以我不在赘述了。

另外,计数题的要求就是不重不漏,对于不重复,直接减去之前已经算好的只包含当前状态的局部的状态的方案数,也就是容斥的本质。
所以很多包含 dp 的容斥题的 dp 状态就是全集的一个子集。最终状态就是全集。转移就是“枚举子集”。

CF449D Jzzhu and Numbers

题目

直接对题目条件容斥。

CF1559E Mocha and Stars

题目

在 gcd 方面,容斥的 trick 就是设 d p [ i ] dp[i] dp[i] 表示 gcd 等于 i i i 的倍数的方案数, a n s [ i ] ans[i] ans[i] 表示 gcd 等于 i 的方案数。求出 d p [ i ] dp[i] dp[i] a n s [ i ] = d p [ i ] − ∑ i ∣ j a n s [ j ] ans[i]=dp[i]-\sum_{i|j} ans[j] ans[i]=dp[i]ijans[j]

对于这道题,考虑如何求出 d p [ i ] dp[i] dp[i]。首先枚举 gcd,假设 gcd 等于 g g g,然后设 f [ i ] [ j ] f[i][j] f[i][j] 表示前 i i i 个数,数字和等于 j × g j\times g j×g 的方案数。转移时间复杂度是 O ( n   l n   m ) O(n\space ln\space m) O(n ln m),总时间复杂度等于 O ( n m   l n   m ) O(nm\space ln\space m) O(nm ln m)

CF1591F Non-equal Neighbours

题目

首先看到不等想到容斥,但是直接容斥肯定解决不了 n ≤ 2 × 1 0 5 n\le 2\times 10^5 n2×105(至少我不会) 。所以考虑设一个很容斥的 dp: f [ i ] f[i] f[i] 表示前 i i i 个数满足条件的方案数。那么 f [ i ] × m i n j = i + 1 n a j f[i]\times min_{j=i+1}^n a_j f[i]×minj=i+1naj 就表示前 i − 1 i-1 i1 个数满足 b i ≠ b i + 1 b_i\neq b_{i+1} bi=bi+1,后面的数满足 b i = b i + 1 b_i=b_{i+1} bi=bi+1 的方案数。

于是转移就是 f [ i ] = ∑ j = 0 i − 1 ( − 1 ) i − j + 1 f [ j ] × m i n k = j + 1 i a k f[i]=\sum_{j=0}^{i-1} (-1)^{i-j+1} f[j]\times min_{k=j+1}^i a_k f[i]=j=0i1(1)ij+1f[j]×mink=j+1iak

考虑优化,令 p o s [ i ] pos[i] pos[i] 表示 [ 1 , i ) [1,i) [1,i) 最后一个小于 a i a_i ai 的位置。

f [ i ] = ∑ j = 0 i − 1 ( − 1 ) i − j + 1 f [ j ] × m i n k = j + 1 i a i f[i]=\sum_{j=0}^{i-1} (-1)^{i-j+1}f[j]\times min_{k=j+1}^i a_i f[i]=j=0i1(1)ij+1f[j]×mink=j+1iai

f [ i ] = ( a i ∑ j = p o s [ i ] + 1 i − 1 ( − 1 ) i − j + 1 f [ j ] ) + ( − 1 ) i − p o s [ i ] ∑ j = 0 p o s [ i ] ( − 1 ) p o s [ i ] − j + 1 f [ j ] × m i n k = j + 1 i a k f[i]=(a_i\sum_{j=pos[i]+1}^{i-1} (-1)^{i-j+1} f[j])+(-1)^{i-pos[i]}\sum_{j=0}^{pos[i]} (-1)^{pos[i]-j+1} f[j]\times min_{k=j+1}^i a_k f[i]=(aij=pos[i]+1i1(1)ij+1f[j])+(1)ipos[i]j=0pos[i](1)pos[i]j+1f[j]×mink=j+1iak

∴ f [ i ] = ( a i ∑ j = p o s [ i ] + 1 i − 1 ( − 1 ) i − j + 1 f [ j ] ) + ( − 1 ) i − p o s [ i ] f [ p o s [ i ] ] \therefore f[i]=(a_i\sum_{j=pos[i]+1}^{i-1} (-1)^{i-j+1} f[j])+(-1)^{i-pos[i]} f[pos[i]] f[i]=(aij=pos[i]+1i1(1)ij+1f[j])+(1)ipos[i]f[pos[i]]

记一个正负交替的前缀和即可。

luogu P6846 [CEOI2019] Amusement Park

题目
f [ s ] f[s] f[s] 包含表示点集的 DAG 数。转移就是枚举当前 DAG 中度为 0 0 0 的点集 t t t,然后 f [ s ] ← f [ s ⊕ t ] f[s]\leftarrow f[s\oplus t] f[s]f[st]
但是当前加入的度为 0 0 0 的集合不一定都会向上一次加入的度为 0 0 0 集合连边,所以会算重。所以转移就是 f [ s ] = ∑ t ⊆ s ( − 1 ) ∣ t ∣ + 1 f [ s ⊕ t ] f[s]=\sum_{t\subseteq s} (-1)^{|t|+1}f[s\oplus t] f[s]=ts(1)t+1f[st]。时间复杂图 O ( 3 n ) O(3^n) O(3n)

ABC321G Electric Circuit

题目
场上读题都读了半天,好菜。
首先设 h s h_s hs 表示点集 s s s 连通的方案数。需要注意的是,点集 s s s 要满足 ∑ i = 1 m [ R i ∈ s ] = ∑ i = 1 m [ B i ∈ s ] \sum_{i=1}^m[R_i\in s]=\sum_{i=1}^m[B_i\in s] i=1m[Ris]=i=1m[Bis]。满足上面条件后,假设 c n t s = ∑ i = 1 m [ R i ∈ s ] cnt_s=\sum_{i=1}^m[R_i\in s] cnts=i=1m[Ris],然后我们有转移 h s = c n t s ! − ∑ t ∈ s h t × c n t s ⊕ t ! h_s=cnt_s!-\sum_{t\in s} h_t\times cnt_{s\oplus t}! hs=cnts!tsht×cntst!
但是可以发现这样转移会出现重复,那么我们钦定 l o w b i t ( s ) ∈ t lowbit(s)\in t lowbit(s)t 也就是点集 s s s 中最小的元素被包含在转移的最后一个连通块里。
然后设 f s f_s fs 表示对于点集 s s s 的虽有连法的连通数总和, g s g_s gs 表示点集 s s s 的方案数。
f s = ∑ t ∈ s f s ⊕ t × h t + g s ⊕ t × h t f_s=\sum_{t\in s} f_{s\oplus t}\times h_t+g_{s\oplus t}\times h_t fs=tsfst×ht+gst×ht
g s = ∑ t ∈ s g s ⊕ t × h t g_s=\sum_{t\in s} g_{s\oplus t}\times h_t gs=tsgst×ht
上面的转移也会出现重复,仍然用前面的方法解决。

ARC160D Mahjong

题目

我们考虑不去对最终的序列求方案数,而是统计可行的操作序列个数,但是这样会算重。那么我们考虑钦定包含 i i i 的区间加 1 1 1 的操作只能执行 < k <k <k 次,那么就没有问题了。
所以现在问题转换成对一个长度为 2 n − k + 1 2n-k+1 2nk+1 的序列统计个数,要求对于 i ∈ [ 1 , 2 n − k + 1 ] i\in[1,2n-k+1] i[1,2nk+1],满足 a i ≥ 0 a_i\ge0 ai0 ∑ i = 1 2 n − k + 1 a i = m k \sum_{i=1}^{2n-k+1}a_i=\frac{m}{k} i=12nk+1ai=km,且 i ∈ [ 1 , n − k + 1 ] i\in[1,n-k+1] i[1,nk+1] a i < k a_i<k ai<k
对满足限制的个数容斥,然后是插板法,式子大概长成这样:
a n s = ∑ i = 0 n − k + 1 ( − 1 ) i ( n − k + 1 i ) ( m k − i × k + 2 n − k 2 n − k ) ans=\sum_{i=0}^{n-k+1}(-1)^i\binom{n-k+1}{i}\binom{\frac{m}{k}-i\times k+2n-k}{2n-k} ans=i=0nk+1(1)i(ink+1)(2nkkmi×k+2nk)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值