『Maths』Record
写在前面
重新进行了排版,现在阳间多了。
数论相关
莫比乌斯反演
简单题在莫比乌斯反演学习笔记里面。
被神仙虐了,来补几道休闲题。
「SDOI2014」数表
题意:求 \(\begin{aligned}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sigma_1(\gcd(i,j))[\gcd(i,j)\le a]\end{aligned}\)
做法:
不妨设 \(n\le m\)
然后如果没有限制这题就没了,直接线性筛算前缀和然后整除分块即可。
问题是这玩意带个 \([\gcd(i,j)\le a]\),咋做?
我们设: \(f(t)=\sum\limits_{d\mid t}\sigma_1(d)\mu(\frac{t}{d})\),然后我们发现当 \(\sigma_1(d)\le a\) 的时候它才对答案贡献。于是我们将所有询问的 \(a\) 从小到大排序,询问的时候每次会多出一些 \(d\) 对 \(f(t)\) 做贡献。由于整除分块需要对 \(f\) 进行区间查询,于是可以使用最好写的树状数组,每次枚举这一轮贡献的 \(d\) 的每个倍数并且单点修改即可。
复杂度 \(O(q\sqrt{n}\log n+n\log^2 n)\),左边是整除分块,右边是处理贡献。
「SDOI2017」数字表格
- 题意:求 \(\begin{aligned}\prod\limits_{i=1}^{n}\prod_{j=1}^{m}f_{\gcd(i,j)}\end{aligned}\),\(f\) 为斐波那契数列。
- 做法:
套路枚举 \(\gcd:\)
和上一题一样,令 \(t=id:\)
外面的 \((n/t)(m/t)\) 告诉我们可以整除分块,考虑里面这玩意咋算。
同上一题,对于每个 \(d\),我们枚举它的倍数,乘上 \(d\) 的贡献即可计算,最后分块的时候搞一个前缀积即可。
令 \(p\) 为模数,预处理 \(\mu\) 和 \(\mathtt{fib}\) 的复杂度暂且忽略不计,预处理斐波那契逆元的复杂度为 \(O(n\log p)\),算贡献的部分由于是枚举倍数,所以是一个调和级数,即 \(O(n\log n)\),整除分块复杂度为 \(O(q\sqrt{n}\log p)\)(因为前缀积还原还要计算逆元)。
所以总复杂度为 \(O(n\log n+n\log p+q\sqrt{n}\log p)\),大致算了一下大概是 \(6.36\times10^7\),时限充裕。
容斥/反演相关
集合反演
或者
CF1770F Koxia and Sequence
- 题意
给定非负整数 \(n,x,y\),对于所有满足 \(\sum\limits_{i=1}^{n}a_i=x\) 并且 \(\text{OR}_{i=1}^{n}a_i=y\) 的 \(\{a_n\}\),求 \(\bigoplus\limits_{i=1}^{n}a_i\) 的异或和。
\(n\le 2^{40},x\le 2^{60},y\le 2^{20}\)。
- 题解
首先根据对称性,当 \(n\) 为偶数时,答案为 \(0\)。所以只考虑 \(n\) 为奇数的情况,为 \(a_1\) 的异或和。
拆位,对每一位 \(t\),计算 \(a_1\) 的第 \(t\) 位为 \(1\) 的方案数 \(\text{mod}\ 2\) 的结果。此时显然 \(\bigoplus\limits_{i=1}^{n}a_i\) 第 \(t\) 位为 \(1\)。
考虑容斥,设 \(g(y)\) 为按位或为 \(y\) 的方案数,\(f(y)\) 为按位或为 \(y\) 的子集的方案数,显然 \(f(y)=\sum\limits_{y'\subseteq y}g(y')\),反演结论得到 \(g(y)=\sum\limits_{y'\subseteq y}(-1)^{|y|-|y'|}f(y')\),前提是 \(y'\) 第 \(t\) 位为 \(1\)。
由于我们只需要得到 \(g(y)\) 的奇偶性,所以我们可以将式子变为 \(g(y)\equiv\bigoplus\limits_{y'\subseteq y}f(y')\mod 2\)。
因为钦定 \(a_1\) 的第 \(t\) 位为 \(1\),我们可以让 \(a_1\) 减去 \(2^t\),此时 \(\sum\limits_{i=1}^{n}a_i=x-2^t\)。 由 \(\text{Lucas}\) 定理推论(组合数奇偶性定理)与 \(\text{Vandermonde}\) 卷积公式得:
所以答案即为:
\(O(y\log y)\) 枚举 \(t,y'\) 即可。
SHOI2016 黑暗前的幻想乡
- 题意:
\(n\) 个点,\(n-1\) 种颜色。每种颜色有 \(m_i\) 条边连接 \(u_j,v_j\) 两个节点。求颜色数为 \(n-1\) 的生成树数量。
\(n\le 17\)。
- 题解:
实在不会一些不太板的数数题……
考虑以颜色为集合状态,令 \(f_{S}\) 为恰有 \(S\) 中颜色的生成树数量,\(g_{S}\) 为颜色在 \(S\) 中的生成树数量。
显然有 \(g_{S}=\sum\limits_{T\subseteq S}f_T\)。那么 \(f_S=\sum\limits_{T\subseteq S}(-1)^{|S|-|T|}g_T\)。
所以答案就是 \(f_U=\sum\limits_{T}(-1)^{n-1-|T|}g_T\),枚举 \(T\) 然后把 \(T\) 所有颜色拉出来求无向图生成树个数即可。
可以 \(\text{matrix\ tree}\) 定理。复杂度 \(O(2^nn^3)\)。
二项式反演
这个形式有点多,最常用的:
不太常用的:
这主要告诉我们 \(A_{ii}=(-1)^i\dbinom{n}{i}\) 这个矩阵是自逆的。
例题有点板。我数学怎么这么菜。
莫比乌斯反演
形式 \(1\)(约数形式):
这是显然的,由 \(f=g*I,\mu =I^{-1}\) 可推出 \(g=f*\mu\)。
形式 \(2\)(倍数形式):
这鬼东西有点抽象,找时间补个证明。
一般用于解决数论问题,找不到什么高妙不板的例题。
下面是科技。
Min-Max 容斥
对于满足全序关系并且其中元素满足可加减性的可重集合 \(S\),有:
证明(参考 OI Wiki
):
考虑构造映射 \(f:S_k\to \{1,2,...,k\}\),\(S_k\) 为 \(S\) 中第 \(k\) 大元素,显然这是双射。
那么 \(f(\min(x,y))=f(x)\cap f(y),f(\max(x,y))=f(x)\cup f(y)\)。
所以:
两边的 \(f\) 都可以映射回去,用类似的证法可以把左式换成最小值,所以 \(\text{Min-Max}\) 容斥成立。
事实上,\(\text{Min-Max}\) 容斥也可以作用于期望:
证明可以考虑期望的定义式,注意 \(S_0\) 代表 \(S\) 所有可能出现元素的并:
需要注意的是倒数第二行 \(\sum\limits_{T\subseteq S'}P(S'=S)\min\{T\}\) 中即使 \(S'\) 带附加条件,这个式子仍然表示的是 \(T\) 的期望最小值,理由可以自行思考(
HAOI2015 按位或
- 题意:
刚开始你有一个数字 \(0\),每一秒钟你会随机选择一个 \([0,2^n-1]\) 的数字,与你手上的数字进行或(C++,C 的 |
,pascal 的 or
)操作。选择数字 \(i\) 的概率是 \(p_i\)。保证 \(0\leq p_i \leq 1\),\(\sum p_i=1\) 。问期望多少秒后,你手上的数字变成 \(2^n-1\)。
\(n\le 20\)。
- 题解:
根据 \(\text{Min-Max}\) 容斥原理:
本题中 \(S\) 代表一个位数的集合,\(\max\{S\}\) 为 \(S\) 中元素最后一个变为 \(1\) 的时间,\(\min\{T\}\) 为 \(T\) 中元素第一个变为 \(1\) 的时间,显然答案就是左式 \(E(max\{S\})\)。
考虑求解 \(E(\min\{T\})\),由于 \(T\) 中至少有一个元素变为 \(1\) 的概率为 \(\sum\limits_{T'\cap T\neq \varnothing}P_{T'}\),根据期望的定义我们知道 \(E(\min\{T\})=\dfrac{1}{\sum\limits_{T'\cap T\neq \varnothing}P_{T'}}\),其中 \(U\) 表示全集 \(\{0,1,...,n-1\}\)。
这个有交的东西比较难搞,正难则反,考虑 \(U\) 的补集,则 \(E(\min\{T\})=\dfrac{1}{\sum\limits_{T'\cap T\neq \varnothing}P_{T'}}=\dfrac{1}{1-\sum\limits_{T'\subseteq U\setminus T}P_{T'}}\)。
于是问题变为求解 \(\sum\limits_{T'\subseteq T}P_{T'}\),这显然是一个 FWT
的或运算变换,直接 \(O(n2^n)\) 做即可。
最后枚举每个 \(T\),求其贡献即可,复杂度 \(O(n2^n)\)。
PKUWC2018 随机游走
- 题意:
给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去。
有 \(Q\) 次询问,每次询问给定一个集合 \(S\),求如果从 \(x\) 出发一直随机游走,直到点集 \(S\) 中所有点都至少经过一次的话,期望游走几步。
特别地,点 \(x\)(即起点)视为一开始就被经过了一次。
\(n\le 18\),\(Q\le 5000\),对 $998244353 $ 取模。
- 题解:
求集合内最大时间的期望,一眼 \(\text{Min-Max}\) 容斥。
为什么我每题都要写一遍这个式子。
左式即为所求,考虑右式 \(E(\min\{T\})\) 怎么做,它的意义为对于每一个 \(T\subseteq S\),求出随机游走并第一次走到 \(u\in T\) 的期望时间。
对于随机游走问题,可以用 dp 解决。
设 \(f_{T,i}\) 表示树上从 \(i\) 游走到第一个 \(T\) 中的点的期望时间。
那么显然:
- \(f_{T,i}=0,i\in T\)
- \(f_{T,i}=1+\frac{1}{deg_i}\sum\limits_{(u,i)\in E}f_{T,u},\text{otherwise}\)
应该注意的是这里状态转移之间包含了环,所以不能直接从下往上或从上往下递推。
对于这类随机游走问题,我们一般使用高斯消元求解,但是这题使用高斯消元是 \(O(n^3)\) 的,预处理就需要 \(O(2^nn^3\log w)\),显然超时。但是树上随机游走问题我们有一些特殊的技巧。
为了简化算式,以下 \(f_{T,i}\) 简记为 \(f_i\),读者需要知道这是对于每一个 \(T\) 而言的。
首先考虑叶子节点 \(u\),显然它能够被表示成 \(A_u+B_u\times f_{fa_u}\) 的形式:如果 \(u\in T\),那么 \(A_u=B_u=0\),否则 \(A_u=B_u=1\)。
然后我们考虑归纳,假设节点 \(u\) 的所有儿子 \(v_1,v_2,...,v_m\) 均可以表示成 \(A_{v_i}+B_{v_i}\times f_u\) 的形式,那么对于节点 \(u\) :
- 显然存在 \(A_u=B_u=0\) 使得 \(f_u=0\),\(u\in T\)
- 若 \(u\notin T\),则:
那就解一个方程即可:
令 \(A_u=\dfrac{deg_u+\sum\limits_{i=1}^{m}A_{v_i}}{deg_u-\sum\limits_{i=1}^{m}B_{v_i}}\),\(B_u=\dfrac{1}{deg_u-\sum\limits_{i=1}^{m}B_{v_i}}\) 即可满足 \(f_u=A_u+B_{u}\times f_{fa_u}\)。
那么我们令 \(x\) 作为根,从儿子向根递推能得到每个点的 \(A_u,B_u\),由于 \(x\) 没有父亲,那么 \(f_{T,x}=A_x\),我们就能 \(O(2^nn\log w)\) 得到对于每一个 \(T\),\(E(\min\{T\})\) 的值,记为 \(g_{T}\)。
那么对于每一个 \(S\),我们只需要求 \(\sum\limits_{T\subseteq S}(-1)^{|T|-1}g_{T}\),跑 FWT
或变换即可。
拓展 Min-Max 容斥
由于我被神仙 sinsop90
踩爆了,所以添加一点内容。
事实上,\(\text{Min-Max}\) 容斥可以求出第 \(k\) 大小:
证明略。
P4707 重返现世
- 题意:
有 \(n\) 种原料,需要集齐任意 \(k\) 种。
每个单位时间会随机生成一种原料。每种原料被生成的概率是不同的,第 \(i\) 种原料被生成的概率是 \(\frac{p_i}{m}\) 。
求收集到任意 \(k\) 种原料的期望时间,答案对 \(998244353\) 取模。
\(n\le 10^3,|n-k|\le 10,m\le 10^4\)。
- 题解:
我们可以把题目看作每个原料有一个生成时间,即求第 \(n-k+1\) 大的期望值。为了简化式子,以下令 \(k\gets n-k+1\),显然 \(k\le 11\),并且求的是第 \(k\) 大的期望。
套用拓展 \(\text{Min-Max}\) 容斥,把前 \(k\) 大转换成最小:
显然对于每一种 \(T\),可以把 \(T\) 中的原料看成一类,其它的看作另一类,那么抽到 \(T\) 中原料的概率显然就是 \(P_T=\dfrac{\sum\limits_{i\in T}p_i}{m}\),由于\(E(\min(T))\) 表示第一次抽到 \(T\) 中原料的期望时间,所以由简单期望知识我们知道 \(E(\min(T))=\dfrac{1}{P_T}=\dfrac{m}{\sum\limits_{i\in T}p_i}\)。
所以
然后考虑 \(dp\),由于 \(k\)、\(m\) 都很小,于是可以纳入状态,令 \(dp_{i,j,k}\) 表示当前考虑前 \(i\) 种原料,\(\sum\limits_{i\in T}p_i=j\) 的时候 \(\sum\limits_{T\subseteq S}\dbinom{|T|-1}{k-1}(-1)^{|T|-k}\) 的值。
转移的话,其实非常显然。
- 首先你可以不取 \(i\),\(dp_{i,j,k}\gets dp_{i-1,j,k}\)。
- 其次,如果你选了 \(i\),那么:
\(\dbinom{|T|-1}{k-1}(-1)^{|T|-k}=\dbinom{|T|-2}{k-2}(-1)^{(|T|-2)-(k-2)}-\dbinom{|T|-2}{k-1}(-1)^{(|T|-2)-(k-1)}\)
于是这种情况可以从 \(dp_{i-1,j-p_i,k}\) 与 \(dp_{i-1,j-p_i,k-1}\) 转移过来。
总的转移式子就是:
\(O(nmk)\) 转移即可,但是注意边界 \(dp_{0,0,0}=0,dp_{0,0,i}=-1(i>0)\)。
单位根反演
这个东西没啥用,但是:
单位根反演常用于求某个多项式特定倍数的系数和。
推论:
集合幂级数
FWT | 快速沃尔什变换
默认你已经会了模板题(求或、与、异或卷积)。
COCI2011-2012#6 KOŠARE
发现 \(m\) 很小,所以一个箱子可以用一个二进制数 \(a_i\) 表示,值域 \(w=2^{20}\)。然后就变成取出若干个 \(a_i\) 使得或起来为全集的方案数。
将所有 \(a_i\) 按位取反,即求若干个 \(a_i\) 与起来为空集的方案数,就是这题。
考虑容斥,令 \(t_{S}\) 为与起来恰为 \(S\) 的方案数,\(g_S\) 为与起来包含 \(S\) 的方案数。显然有 \(g_S=\sum\limits_{S\subseteq T}t_T\),反演得到 \(t_{S}=\sum\limits_{S\subseteq T}(-1)^{|S|-|T|}g_T\)。由于我们要求 \(t_{\varnothing}\),即为 \(\sum\limits_{T}(-1)^{|T|}g_T\)。由于可以 \(O(w)\) 枚举 \(T\),我们现在考虑如何求 \(g\)。
由于与起来包含 \(S\),所以你选出来每个数都包含 \(S\),所以 \(g_S=2^{f_S}-1\),\(f_S\) 为包含 \(S\) 的数的个数。
显然 \(f\) 是个超集和,想一下 FWT 求子集和的时候,把前面贡献后面,那么现在在后面贡献前面即可。
然后就做完了。复杂度 \(O(n+w\log w)\)。
FST | 子集卷积相关
Luogu6097【模板】子集卷积
其实是暴力。
因为这是模板题,所以模板的前置知识也要讲。
- 前置知识:FWT 计算或卷积。
这里只需要掌握快速计算或卷积的方法,所以内容较少。如果向了解更多(比如异或卷积)的话可以去 P4717 看看。
例题:给定长度为 \(2^n\) 的序列 \(a,b\),求 \(c_k=\sum\limits_{i|j=k}a_ib_j\) 序列中每一项的值。我们需要一个 \(O(n\log n)\) 的解法。
考虑根据 \(a,b\) 构造两个序列 \(A,B\),若 \(a\to A,b\to B\) 均为 \(O(n\log n)\) 并且这个过程可逆,令 \(C_i=A_i\times B_i\),若 \(C\) 能还原回 \(c\),那么我们就可以 \(O(n\log n)\) 计算 \(c\)。
在这里,我们令 \(A_i=\sum\limits_{j|i=i}a_j\)(也就是 \(j\) 为 \(i\) 的子集)。那么有 \(C_i=\sum\limits_{(j|k)|i=i}a_jb_k\)。
那么有:
也就是说我们证明了这个 \(A,B\) 是的确能映射到一个正确的 \(C\) 的。现在考虑如何快速求 \(A_i=\sum\limits_{j|i}a_j\)。
显然可以从低到高枚举每个二进制位,然后当前位为 \(0\) 的是右边对应位置为 \(1\) 的子集,从左依次贡献到右即可。
\(C\to c\) 相当于求一个逆过程,右边依次减去左边的贡献即可。
参考了这里的代码。
void fwt(int *s, int op) {
op = (op + mod) % mod;
for (int o = 2, k = 1; o <= S + 1; o <<= 1, k <<= 1)
for (int i = 0; i <= S; i += o)
for (int j = 0; j < k; j++)
(s[i + j + k] += 1ll * s[i + j] * op % mod) %= mod;
}
- 回到原题
你发现这东西就多加了一个限制 \(i\&j=0\),也就是说 \(i,j\) 无交。
考虑一个充要条件,\(i\&j=0\) 并且 \(i|j=k\) 其实就相当于 \(|i|+|j|=|k|\) 并且 \(i|j=k\),\(|i|\) 表示 \(i\) 集合的大小,即 \(i\) 中 \(1\) 的个数。
所以可以预处理 \(f_{i,j}\) 表示满足 \(|j|=i\) 的 \(a_j\) 的值,\(g_{i,j}\) 对 \(b\) 同理。
那么 \(c_{k}=\sum\limits_{i=0}^n\sum\limits_{j=0}^{2^n}\sum\limits_{j|l=k}f_{i,j}g_{k-i,l}\)。
令 \(h_{i}=\sum\limits_{k=0}^nf_{k}*g_{i-k}\),\(*\) 表示进行或卷积,那么 \(c_i=h_{|i|,i}\)。
FWT 预处理每个 \(f_k\) 和 \(g_k\) 的子集和,枚举这个 \(i,k\) 求出 \(h\) 的子集和,然后做逆的 FWT 就做完了。复杂度 \(O(n\log^2 n)\)。
CF1034E Little C Loves 3 III
太神仙了。
直接子集卷积肯定是不行的,1s 的时限和 62MB 的空间摆在那里。
那就要考虑使用模 \(4\) 的性质乱搞了。
我们考虑给每个 \(i\),不管它符不符合条件,赋一个权值。如果 \(i\ \text{and}\ j\neq 0\),它对答案是没有贡献的,否则它能贡献到 \(i\ \text{or}\ j\) 的位置。
那考虑所有没贡献 \((i,j)\),我们想装模做样地给它贡献到 \(i\ \text{or}\ j\),就需要 \(i\) 和 \(j\) 的权值“抵消”掉。下面是一个十分精妙的想法:
由于 \(i\ \text{and}\ j\neq 0\),那么 \(|i|+|j|\ge|i\ \text{or}\ j|\)。我们可以给每个 \(a_i\) 赋为 \(a_i\times4^{\text{popcount(i)}}\),\(b\) 同理,我们计算 \(c_k=\sum\limits_{i\ \text{or}\ j=k}a_ib_j\),那么 \(c_k\) 中 \(i\ \text{and}\ j\) 不为 \(0\) 的项的乘积必然能被 \(4^{\text{popcount(k)+1}}\) 整除,不做贡献,所以最后 \(c_k\) 直接除 \(4^{\text{popcount(k)}}\) 再模 \(4\) 就是正确的答案。
显然对于合法的 \(i,j\),对 \(c_k\) 的贡献按照上述方法计算,还是单次的。
然后就做完了,计算 \(c\) 需要 FWT,所以复杂度 \(O(n2^n)\)。
太神仙了。
WC2018 州区划分
有一个显然的状压,设 \(f_S\) 表示划分完城市集合 \(S\) 之后的答案。
要求 \(T\) 中不包含欧拉回路。
显然可以 \(O(n2^n)\) 预处理 \(g_S=\sum\limits_{i\in S}w_i\),要求 \(S\) 合法:
然后这是个显然的子集卷积,做完了,\(O(n^22^n)\)。
CF838C Future Failure
考虑先手必胜的充要条件。
实际上,只要 \(n\) 为奇数或者本质不同排列为偶数时先手必胜。
\(n\) 为奇数时,先手必胜,答案就是 \(k^n\)。
\(n\) 为偶数时,令 \(a_i\) 为第 \(i\) 个字符出现次数,\(\sum\limits_{i=1}^ka_i=n\)。反面考虑,我们相当于求 \(\dbinom{n}{a_1\ a_2\ ...\ a_k}\) 为奇数的方案数。
根据 Lucas 定理:
其中 \(m=\sum\limits_{i=0}^qp^{i}m_i\),\(n\) 同理。
显然这里令 \(p\) 为 \(2\),\(m_i,n_i\in\{0,1\}\)。这告诉我们 \(\dbinom{n}{a_1\ a_2\ ...\ a_k}\) 为奇数,相当于 \(\forall i\neq j,a_i\&a_j=0\)。
考虑一个 dp,\(f_{i,j}\) 表示前考虑 \(i\) 个字符,目前 \(\sum a_i\) 为 \(j\) 的方案数。那么有转移方程:
这东西显然是个子集卷积,预处理 \(g_{|i|,i}=\frac{1}{i!}\) 的子集和,暴力做 \(O(kn\log^2n)\)。
然后你死了,最大的点跑了 13 秒,而且空间爆了。考虑优化。
我们考虑指数生成函数暴力 exp 取 ln 然后就做完了。
其实每次转移的 \(g\) 都是相同的,这让我们想到了快速幂。
借用快速幂的思想,省略每次重复计算 \(f\) 卷 \(g\) 的若干次,复杂度 \(O(n\log^2n\log k)\)。
挺卡常,但这总比多项式好吧。
组合计数
斯特林数
普通幂转下降幂:
Luogu 2791 幼儿园篮球题
虽然我们家哥哥的房塌了……但这不影响我们卷题啊!
考虑枚举选出来 \(i\) 个没气的篮球,那么答案可以表示成:
注意到这里的组合数 \(\dbinom{n}{m}\) 在 \(n<m\) 或者 \(m<0\) 时无意义,直接当成 \(0\) 即可。
考虑普通幂转下降幂:
带入原式有:
根据经典组合恒等式:
代入原式得:
第三步运用了范德蒙德卷积。
于是我们只需要求出第 \(L\) 行的斯特林数值,就可以通过 \(O(N)\) 预处理阶乘及其逆元,对于每个询问 \(O(L)\) 得出答案。
这是个经典 trick,通过二项式反演以及 NTT 可以 \(O(L\log L)\)求出,可以看 P5395 第二类斯特林数·行,这里不多赘述。
总复杂度 \(O(N+L(\log L+q))\)。