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]−∑i∣jans[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
n≤2×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
i−1 个数满足
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=0i−1(−1)i−j+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=0i−1(−1)i−j+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]=(ai∑j=pos[i]+1i−1(−1)i−j+1f[j])+(−1)i−pos[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]=(ai∑j=pos[i]+1i−1(−1)i−j+1f[j])+(−1)i−pos[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[s⊕t]。
但是当前加入的度为
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]=∑t⊆s(−1)∣t∣+1f[s⊕t]。时间复杂图
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[Ri∈s]=∑i=1m[Bi∈s]。满足上面条件后,假设
c
n
t
s
=
∑
i
=
1
m
[
R
i
∈
s
]
cnt_s=\sum_{i=1}^m[R_i\in s]
cnts=∑i=1m[Ri∈s],然后我们有转移
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!−∑t∈sht×cnts⊕t!。
但是可以发现这样转移会出现重复,那么我们钦定
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=∑t∈sfs⊕t×ht+gs⊕t×ht。
g
s
=
∑
t
∈
s
g
s
⊕
t
×
h
t
g_s=\sum_{t\in s} g_{s\oplus t}\times h_t
gs=∑t∈sgs⊕t×ht。
上面的转移也会出现重复,仍然用前面的方法解决。
ARC160D Mahjong
我们考虑不去对最终的序列求方案数,而是统计可行的操作序列个数,但是这样会算重。那么我们考虑钦定包含
i
i
i 的区间加
1
1
1 的操作只能执行
<
k
<k
<k 次,那么就没有问题了。
所以现在问题转换成对一个长度为
2
n
−
k
+
1
2n-k+1
2n−k+1 的序列统计个数,要求对于
i
∈
[
1
,
2
n
−
k
+
1
]
i\in[1,2n-k+1]
i∈[1,2n−k+1],满足
a
i
≥
0
a_i\ge0
ai≥0,
∑
i
=
1
2
n
−
k
+
1
a
i
=
m
k
\sum_{i=1}^{2n-k+1}a_i=\frac{m}{k}
∑i=12n−k+1ai=km,且
i
∈
[
1
,
n
−
k
+
1
]
i\in[1,n-k+1]
i∈[1,n−k+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=0∑n−k+1(−1)i(in−k+1)(2n−kkm−i×k+2n−k)