有 n 个奖项,获得 S 中的奖项的人数为 g(S) ,求获得至少一个奖项的人数。( 不妨认为g(∅)=0 )
∑S(−1)|S|−1g(S)
记容斥系数为 f(|S|),那么对于 ∀i∈[0,n] 应该有:
i∑j=1(ij)f(j)=[i≥1]
f(i)=(−1)i−1 恰好满足。
错排问题:
记 f(i) 为至少有 i 个位置不满足的容斥系数
n∑i=0f(i)(ni)(n−i)!
i∑j=0(ij)f(j)=[i=0]
⇒f(i)=(−1)i
变式:如果 k 个位置满足错排有 ak 的贡献,求所有排列贡献和。
i∑j=0(ij)f(j)=ai
可以递推计算 f
这就是一般化的容斥
快速计算 f:
-
打表找规律
i∑j=0(ij)f(j)=aii∑j=01(i−j)!f(j)j!=aii!
然后就可以多项式求逆做了。
条件的使用
T1 Emiya 家的饭
记 si=∑mj=1ai,j
dpi,j,k :前 i 个方法,第 p 种食材选 j 个,其他食材选 k 个
dpi,j,k=dpi−1,j,k−1ai,p+dpi−1,j−1,k(si−ai,p)+dpi−1,j,k
满足要求的状态为 j>k , 所以只需知道 j,k 相对大小,复杂度为 O(n2m)
T2
考虑容斥,枚举不被覆盖的格子的集合,对于剩余能放车的格子方案数为 2。
同一列的格子联通,那么记选出的格子所在列构成的集合为 S,这些列是无法放置車的。
现在我们先枚举 S,然后再容斥。
此时可以对每一个行极大连通块独立考虑。具体的,对于一个含有 l 列 , 其中 p 列在 S 中的行,枚举这一行上的 p 个位置有哪一些位置选择了不覆盖,有两种情况:
但这样计算会有问题,因为无法确定选出的点是否对应 S,即 S 中可能存在若干列未选出不覆盖的点。
那么再次容斥,我们更改 S 的定义为不选車的列,并枚举未选出不覆盖点的列的集合 T(T⊆S)。记该行有 q 列在 T 中。
总贡献即为:
2l−p+p−q∑i=1(−1)i(p−qi)=2l−p−[p≠q]
再把所有行的贡献乘起来,意义显然。
一个行的贡献只与 l,p,q 有关,那么将原图划分成如下图形,使同颜色的行贡献相同:

这不就是小根笛卡尔树嘛!!!
设 fu,i,j 表示以 u 为根的子树,有 i 列在 S 中,有 j 列在 T 中的贡献。
进一步,我们只需知道 [p=q] ,那么第三维可以改为是否存在一列在 S 中却不在 T 中。
转移时枚举当前节点对应的列的选择情况即可。
时间复杂度 O(n2logn)。
T3
有一个 n×m 的矩阵,填入 [0,m] 中的数并满足:
-
ai,j<ai,j+1
-
ai,j<ai−1,j+1
求方案数。 1≤n,m≤106
每一行用 m+1 个数构成长度为 m 的上升序列,只需确定没有填的数就可以知道序列。
那么记 fi,j 表示填完前 i 行,第 i 行未填的数为 j 的方案数,有:
fi,j=j+1∑k=0fi−1,k
fi,j={fi−1,0+fi−1,1j=0fi,j−1+fi−1,j+1j≠0
问题转化为从 (0,0) 走到 P(n+m+1,n) ,且不经过直线 l1:y=x+1 和 l2:y=x−(m+2) 的方案数
将路径按经过直线顺序分类,并删去重复经过的部分。
所有不合法路径均可以分类为 1212... 或 2121...
先考虑 1212...,即先经过 l1
注意到将 P 按 l1 翻折后得到 P′ , OP′ 的结尾一定为 1 或 12,将 P′ 按 l2 翻折得到 P′′, OP′′ 的结尾一定为 21 或 212
那么我们不断翻折 P 即可,相信大家都知道关于直线 y=x+b 的对称点为 (y0−b,x0+b)
终止状态为 P′(x′,y′) 不在第一象限,x,y正半轴内,因为此时会向左、下走。
每次翻折与对称轴的距离会增加 1,那么只会有 O(n) 次操作。
状态的简并
T4
首先 min−max 容斥得到:
E(max(S))=∑T⊆S(−1)|T|−1E(min(T))
令 AS=∑i∈Sai
令 d=AUAT ,表示选到 T 中元素的期望次数。
再考虑如何求 E(min(T)),一个转化是:
E(min(T))=d∑k≥0P(min(T)>k)
而 k 轮(均选中 T 中元素)没结束的情况是:所有数的和为 k 且每个数小于对应的 bi ,概率即为:
∑∑ci=k,ci<bi∏(aiAT)cik!∏ci!
将每一位的贡献提出来,这样就可以按位计算:
k!ATk∑∑ci=k,ci<bi∏aicici!
令 fi,j 表示前 i 个元素,c 的和为 j 的贡献,有:
fi,j=min(bi−1,j)∑l=0fi−1,j−lailATll!
这样我们得到了 O(2nn2m2) 的暴力
E(max(S))=∑T⊆S(−1)|T|−1AUAT∑k≥0k!ATk∑∑ci=k,ci<bi∏aicici!
E(max(S))=AU∑k≥0k!∑T⊆S(−1)|T|−1ATk+1∑∑ci=k,ci<bi∏aicici!
前面系数有关的量只有 k,AT,|T|,全部压进状态里:
fi,0/1,j,k: 前 i 个数,选中元素个数的奇偶,选中的元素的 a 的和为 j , ∑c=k 的贡献。
fi,0/1,j,k=fi−1,0/1,j,k+min(bi−1,k)∑l=0fi−1,1/0,j−ai,k−laill!
答案即为:
E(max(S))=AU∑k≥0k!S∑j=11jk+1(fn,1,j,k−fn,0,j,k)
注意到容斥系数的改变为 -1,可以直接将第二维丢掉。
优化状态
T5
设 fu,i,S 表示子树 u 内的点,u 对应的点为 i,子树内对应的点的集合为 S 的方案数。
枚举子集转移,复杂度 O(n33n)
如果去掉 S,那么编号可能重复,考虑容斥,枚举所有点对应的点的集合。
n∑j=i(n−ij−i)f(j)=[i=n]
可得: f(i)=(−1)n−i ,直接枚举 S 再 dp 即可。
复杂度 O(2nn3)
容斥系数的处理
T6
先将 n! 唯一分解。
考虑到 ai 相同时 bi 无序,ai 不同时 bi 有序,那么直接看作 bi 有序,最后答案除上 ∏cnt[ai]!
由于 m 不大,尝试划分为若干集合,且钦定每个集合的 bi 相同。
第一部分:容斥系数
令大小为 i 的集合的容斥系数为 fi。
一个划分 T 为若干集合的集合 ({S1...Sk}),定义它的容斥系数为集合的容斥系数之积,记为 gT。
那么一个划分被统计的贡献为:
k∏i=1∑T|SigT
只需满足:
∑T|SigT=[Si=1]
fn+n−1∑i=1(n−1i−1)fi(∑T′|Si′gT′)=[n=1]fn+n−1∑i=1(n−1i−1)fi[n−i=1]=[n=1]fn=[n=1]−(n−1)fn−1
第二部分:方案数
将同一个集合的 ai 相加得到 Ai
每个质因子可以独立计算,相当于完全背包。
总时间复杂度 O(Bell(n)nm)
注意到方案数只与 |Si| 与 Ai 有关,可以用一个状压 dp 合并方案。
大概是 map 套 set,为了卡常可以使用 hash 比较
这样的方案数大概是划分数级别?
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现