『Maths』Record

写在前面#

重新进行了排版,现在阳间多了。

数论相关#

莫比乌斯反演#

简单题在莫比乌斯反演学习笔记里面。
被神仙虐了,来补几道休闲题。

「SDOI2014」数表#

题意:求 i=1nj=1mσ1(gcd(i,j))[gcd(i,j)a]
做法:
不妨设 nm

i=1nj=1mσ1(gcd(i,j))=d=1ni=1ndj=1mdσ1(d)[gcd(i,j)=1]=d=1nσ1(d)i=1ndj=1mdpi,pjμ(p)这步把 gcd 扔到外面,然后后面莫反=d=1nσ1(d)p=1nμ(p)ndpmdp把 p 扔到外面,枚举 p=t=1nntmtdtσ1(d)μ(td) 令 t=dp

然后如果没有限制这题就没了,直接线性筛算前缀和然后整除分块即可。
问题是这玩意带个 [gcd(i,j)a],咋做?
我们设: f(t)=dtσ1(d)μ(td),然后我们发现当 σ1(d)a 的时候它才对答案贡献。于是我们将所有询问的 a 从小到大排序,询问的时候每次会多出一些 df(t) 做贡献。由于整除分块需要对 f 进行区间查询,于是可以使用最好写的树状数组,每次枚举这一轮贡献的 d 的每个倍数并且单点修改即可。
复杂度 O(qnlogn+nlog2n),左边是整除分块,右边是处理贡献。

「SDOI2017」数字表格#

  • 题意:求 i=1nj=1mfgcd(i,j)f 为斐波那契数列。
  • 做法:
    套路枚举 gcd:

i=1nj=1mfgcd(i,j)=d=1nfdi=1n/dj=1m/d[gcd(i,j)=1]=d=1nfdi=1n/dμ(i)(n/id)(m/id)

和上一题一样,令 t=id

d=1nfdi=1n/dμ(i)(n/id)(m/id)=t=1ndtfdμ(t/d)(n/t)(m/t)=t=1n(dtfdμ(t/d))(n/t)(m/t)

外面的 (n/t)(m/t) 告诉我们可以整除分块,考虑里面这玩意咋算。
同上一题,对于每个 d,我们枚举它的倍数,乘上 d 的贡献即可计算,最后分块的时候搞一个前缀积即可。
p 为模数,预处理 μfib 的复杂度暂且忽略不计,预处理斐波那契逆元的复杂度为 O(nlogp),算贡献的部分由于是枚举倍数,所以是一个调和级数,即 O(nlogn),整除分块复杂度为 O(qnlogp)(因为前缀积还原还要计算逆元)。
所以总复杂度为 O(nlogn+nlogp+qnlogp),大致算了一下大概是 6.36×107,时限充裕。

容斥/反演相关#

集合反演#

f(S)=TSg(T)

g(S)=TS(1)|S||T|f(T)

或者

f(S)=STg(T)

g(S)=ST(1)|T||S|f(T)

CF1770F Koxia and Sequence#

  • 题意

给定非负整数 n,x,y,对于所有满足 i=1nai=x 并且 ORi=1nai=y{an},求 i=1nai 的异或和。

n240,x260,y220

  • 题解

首先根据对称性,当 n 为偶数时,答案为 0。所以只考虑 n 为奇数的情况,为 a1 的异或和。

拆位,对每一位 t,计算 a1 的第 t 位为 1 的方案数 mod 2 的结果。此时显然 i=1nait 位为 1

考虑容斥,设 g(y) 为按位或为 y 的方案数,f(y) 为按位或为 y 的子集的方案数,显然 f(y)=yyg(y),反演结论得到 g(y)=yy(1)|y||y|f(y),前提是 yt 位为 1

由于我们只需要得到 g(y) 的奇偶性,所以我们可以将式子变为 g(y)yyf(y)mod2

因为钦定 a1 的第 t 位为 1,我们可以让 a1 减去 2t,此时 i=1nai=x2t。 由 Lucas 定理推论(组合数奇偶性定理)与 Vandermonde 卷积公式得:

f(y)=ai=x2t[a1y2t][a2y][a3y]...[any]ai=x2t(y2ta1)(ya2)(ya3)...(yan)mod2(ny2tx2t)mod2[x2tny2t]mod2

所以答案即为:

t2tf(y)=t2tyy,2tyg(y)=t2tyy,2ty[x2tny2t]

O(ylogy) 枚举 t,y 即可。

SHOI2016 黑暗前的幻想乡#

  • 题意:

n 个点,n1 种颜色。每种颜色有 mi 条边连接 uj,vj 两个节点。求颜色数为 n1 的生成树数量。

n17

  • 题解:

实在不会一些不太板的数数题……

考虑以颜色为集合状态,令 fS 为恰有 S 中颜色的生成树数量,gS 为颜色在 S 中的生成树数量。

显然有 gS=TSfT。那么 fS=TS(1)|S||T|gT

所以答案就是 fU=T(1)n1|T|gT,枚举 T 然后把 T 所有颜色拉出来求无向图生成树个数即可。

可以 matrix\ tree 定理。复杂度 O(2nn3)

二项式反演#

这个形式有点多,最常用的:

f(n)=i=0n(ni)g(i)

g(n)=i=0n(1)ni(ni)f(i)

不太常用的:

f(n)=i=0n(1)i(ni)g(i)

g(n)=i=0n(1)i(ni)f(i)

这主要告诉我们 Aii=(1)i(ni) 这个矩阵是自逆的。

例题有点板。我数学怎么这么菜。

莫比乌斯反演#

形式 1(约数形式):

f(n)=dng(d)

g(n)=dnμ(d)f(nd)

这是显然的,由 f=gI,μ=I1 可推出 g=fμ

形式 2(倍数形式):

f(n)=ndg(d)

g(n)=ndμ(dn)f(d)

这鬼东西有点抽象,找时间补个证明。

一般用于解决数论问题,找不到什么高妙不板的例题。


下面是科技。

Min-Max 容斥#

对于满足全序关系并且其中元素满足可加减性的可重集合 S,有:

max{S}=TS(1)|T|1min{T}

min{S}=TS(1)|T|1max{T}

证明(参考 OI Wiki ):

考虑构造映射 f:Sk{1,2,...,k}SkS 中第 k 大元素,显然这是双射。

那么 f(min(x,y))=f(x)f(y),f(max(x,y))=f(x)f(y)

所以:

|f(max{S})|=|tSf(t)|=TS(1)|T|1|tTf(t)|=TS(1)|T|1|f(min{T})|

两边的 f 都可以映射回去,用类似的证法可以把左式换成最小值,所以 Min-Max 容斥成立。

事实上,Min-Max 容斥也可以作用于期望:

E(max{S})=TS(1)|T|1E(min{T})

E(min{S})=TS(1)|T|1E(max{T})

证明可以考虑期望的定义式,注意 S0 代表 S 所有可能出现元素的并:

E(max{S})=SS0P(S=S)max{S}=SS0P(S=S)TS(1)|T|1min{T}=TS0(1)|T|1TSP(S=S)min{T}=TS0(1)|T|1E(min(T))

需要注意的是倒数第二行 TSP(S=S)min{T} 中即使 S 带附加条件,这个式子仍然表示的是 T 的期望最小值,理由可以自行思考(

HAOI2015 按位或#

  • 题意:

刚开始你有一个数字 0,每一秒钟你会随机选择一个 [0,2n1] 的数字,与你手上的数字进行或(C++,C 的 |,pascal 的 or)操作。选择数字 i 的概率是 pi。保证 0pi1pi=1 。问期望多少秒后,你手上的数字变成 2n1

n20

  • 题解:

根据 Min-Max 容斥原理:

E(max{S})=TS(1)|T|1E(min{T})

本题中 S 代表一个位数的集合,max{S}S 中元素最后一个变为 1 的时间,min{T}T 中元素第一个变为 1 的时间,显然答案就是左式 E(max{S})

考虑求解 E(min{T}),由于 T 中至少有一个元素变为 1 的概率为 TTPT,根据期望的定义我们知道 E(min{T})=1TTPT,其中 U 表示全集 {0,1,...,n1}

这个有交的东西比较难搞,正难则反,考虑 U 的补集,则 E(min{T})=1TTPT=11TUTPT

于是问题变为求解 TTPT,这显然是一个 FWT 的或运算变换,直接 O(n2n) 做即可。

最后枚举每个 T,求其贡献即可,复杂度 O(n2n)

PKUWC2018 随机游走#

  • 题意:

给定一棵 n 个结点的树,你从点 x 出发,每次等概率随机选择一条与所在点相邻的边走过去。

Q 次询问,每次询问给定一个集合 S,求如果从 x 出发一直随机游走,直到点集 S 中所有点都至少经过一次的话,期望游走几步。

特别地,点 x(即起点)视为一开始就被经过了一次。

n18Q5000,对 998244353 取模。

  • 题解:

求集合内最大时间的期望,一眼 Min-Max 容斥。

E(max{S})=TS(1)|T|1E(min{T})

为什么我每题都要写一遍这个式子。

左式即为所求,考虑右式 E(min{T}) 怎么做,它的意义为对于每一个 TS,求出随机游走并第一次走到 uT 的期望时间。

对于随机游走问题,可以用 dp 解决。

fT,i 表示树上从 i 游走到第一个 T 中的点的期望时间。

那么显然:

  • fT,i=0,iT
  • fT,i=1+1degi(u,i)EfT,u,otherwise

应该注意的是这里状态转移之间包含了环,所以不能直接从下往上或从上往下递推。

对于这类随机游走问题,我们一般使用高斯消元求解,但是这题使用高斯消元是 O(n3) 的,预处理就需要 O(2nn3logw),显然超时。但是树上随机游走问题我们有一些特殊的技巧。

为了简化算式,以下 fT,i 简记为 fi,读者需要知道这是对于每一个 T 而言的。

首先考虑叶子节点 u,显然它能够被表示成 Au+Bu×ffau 的形式:如果 uT,那么 Au=Bu=0,否则 Au=Bu=1

然后我们考虑归纳,假设节点 u 的所有儿子 v1,v2,...,vm 均可以表示成 Avi+Bvi×fu 的形式,那么对于节点 u

  • 显然存在 Au=Bu=0 使得 fu=0uT
  • uT,则:

fu=1+1degu(ffau+i=1mAvi+Bvi×fu)

那就解一个方程即可:

fu=degu+i=1mAvidegui=1mBvi+ffaudegui=1mBvi

Au=degu+i=1mAvidegui=1mBviBu=1degui=1mBvi 即可满足 fu=Au+Bu×ffau

那么我们令 x 作为根,从儿子向根递推能得到每个点的 Au,Bu,由于 x 没有父亲,那么 fT,x=Ax,我们就能 O(2nnlogw) 得到对于每一个 TE(min{T}) 的值,记为 gT

那么对于每一个 S,我们只需要求 TS(1)|T|1gT,跑 FWT 或变换即可。

拓展 Min-Max 容斥#

由于我被神仙 sinsop90 踩爆了,所以添加一点内容。

事实上,Min-Max 容斥可以求出第 k 大小:

maxk{S}=TS(1)|T|k(|T|1k1)min{T}

mink{S}=TS(1)|T|k(|T|1k1)max{T}

E(maxk{S})=TS(1)|T|k(|T|1k1)E(min{T})

E(mink{S})=TS(1)|T|k(|T|1k1)E(max{T})

证明略。

P4707 重返现世#

  • 题意:

n 种原料,需要集齐任意 k 种。

每个单位时间会随机生成一种原料。每种原料被生成的概率是不同的,第 i 种原料被生成的概率是 pim

求收集到任意 k 种原料的期望时间,答案对 998244353 取模。

n103,|nk|10,m104

  • 题解:

我们可以把题目看作每个原料有一个生成时间,即求第 nk+1 大的期望值。为了简化式子,以下令 knk+1,显然 k11,并且求的是第 k 大的期望。

套用拓展 Min-Max 容斥,把前 k 大转换成最小:

E(maxk(S))=TS(|T|1k1)(1)|T|kE(min(T))

显然对于每一种 T,可以把 T 中的原料看成一类,其它的看作另一类,那么抽到 T 中原料的概率显然就是 PT=iTpim,由于E(min(T)) 表示第一次抽到 T 中原料的期望时间,所以由简单期望知识我们知道 E(min(T))=1PT=miTpi

所以

ansk=TS(|T|1k1)(1)|T|kmiTpi=mTS(|T|1k1)(1)|T|kiTpi

然后考虑 dp,由于 km 都很小,于是可以纳入状态,令 dpi,j,k 表示当前考虑前 i 种原料,iTpi=j 的时候 TS(|T|1k1)(1)|T|k 的值。

转移的话,其实非常显然。

  • 首先你可以不取 idpi,j,kdpi1,j,k
  • 其次,如果你选了 i,那么:

(|T|1k1)(1)|T|k=(|T|2k2)(1)(|T|2)(k2)(|T|2k1)(1)(|T|2)(k1)

于是这种情况可以从 dpi1,jpi,kdpi1,jpi,k1 转移过来。

总的转移式子就是:

dpi,j,k=dpi1,j,k+dpi1,jpi,k1dpi1,jpi,k

O(nmk) 转移即可,但是注意边界 dp0,0,0=0,dp0,0,i=1(i>0)

单位根反演#

[nk]=1nd=0n1ωnik

这个东西没啥用,但是:

单位根反演常用于求某个多项式特定倍数的系数和。

i=0nk[xik]f(x)=i=0n[ki][xi]f(x)=i=0n[xi]f(x)1kj=0k1ωkij=1ki=0naij=0k1ωkij=1ki=0nj=0k1ai(ωkj)i=1kj=0k1f(ωkj)

推论:

i=0nk[xik+r]f(x)=1kj=0k1f(ωkj)ωkir

集合幂级数#

FWT | 快速沃尔什变换#

默认你已经会了模板题(求或、与、异或卷积)。

COCI2011-2012#6 KOŠARE#

发现 m 很小,所以一个箱子可以用一个二进制数 ai 表示,值域 w=220。然后就变成取出若干个 ai 使得或起来为全集的方案数。

将所有 ai 按位取反,即求若干个 ai 与起来为空集的方案数,就是这题

考虑容斥,令 tS 为与起来恰为 S 的方案数,gS 为与起来包含 S 的方案数。显然有 gS=STtT,反演得到 tS=ST(1)|S||T|gT。由于我们要求 t,即为 T(1)|T|gT。由于可以 O(w) 枚举 T,我们现在考虑如何求 g

由于与起来包含 S,所以你选出来每个数都包含 S,所以 gS=2fS1fS 为包含 S 的数的个数。

显然 f 是个超集和,想一下 FWT 求子集和的时候,把前面贡献后面,那么现在在后面贡献前面即可。

然后就做完了。复杂度 O(n+wlogw)

FST | 子集卷积相关#

Luogu6097【模板】子集卷积#

其实是暴力。

因为这是模板题,所以模板的前置知识也要讲。

  • 前置知识:FWT 计算或卷积。

这里只需要掌握快速计算或卷积的方法,所以内容较少。如果向了解更多(比如异或卷积)的话可以去 P4717 看看。

例题:给定长度为 2n 的序列 a,b,求 ck=i|j=kaibj 序列中每一项的值。我们需要一个 O(nlogn) 的解法。

考虑根据 a,b 构造两个序列 A,B,若 aA,bB 均为 O(nlogn) 并且这个过程可逆,令 Ci=Ai×Bi,若 C 能还原回 c,那么我们就可以 O(nlogn) 计算 c

在这里,我们令 Ai=j|i=iaj(也就是 ji 的子集)。那么有 Ci=(j|k)|i=iajbk

那么有:

Ai×Bi=(j|i=iaj)(j|i=ibj)=j|i=i,k|i=iajbk=(j|k)|i=iajbk=Ci

也就是说我们证明了这个 A,B 是的确能映射到一个正确的 C 的。现在考虑如何快速求 Ai=j|iaj

显然可以从低到高枚举每个二进制位,然后当前位为 0 的是右边对应位置为 1 的子集,从左依次贡献到右即可。

Cc 相当于求一个逆过程,右边依次减去左边的贡献即可。

参考了这里的代码。

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 集合的大小,即 i1 的个数。

所以可以预处理 fi,j 表示满足 |j|=iaj 的值,gi,jb 同理。

那么 ck=i=0nj=02nj|l=kfi,jgki,l

hi=k=0nfkgik 表示进行或卷积,那么 ci=h|i|,i

FWT 预处理每个 fkgk 的子集和,枚举这个 i,k 求出 h 的子集和,然后做逆的 FWT 就做完了。复杂度 O(nlog2n)

CF1034E Little C Loves 3 III#

太神仙了。

直接子集卷积肯定是不行的,1s 的时限和 62MB 的空间摆在那里。

那就要考虑使用模 4 的性质乱搞了。

我们考虑给每个 i,不管它符不符合条件,赋一个权值。如果 i and j0,它对答案是没有贡献的,否则它能贡献到 i or j 的位置。

那考虑所有没贡献 (i,j),我们想装模做样地给它贡献到 i or j,就需要 ij 的权值“抵消”掉。下面是一个十分精妙的想法:

由于 i and j0,那么 |i|+|j||i or j|。我们可以给每个 ai 赋为 ai×4popcount(i)b 同理,我们计算 ck=i or j=kaibj,那么 cki and j 不为 0 的项的乘积必然能被 4popcount(k)+1 整除,不做贡献,所以最后 ck 直接除 4popcount(k) 再模 4 就是正确的答案。

显然对于合法的 i,j,对 ck 的贡献按照上述方法计算,还是单次的。

然后就做完了,计算 c 需要 FWT,所以复杂度 O(n2n)

太神仙了。

WC2018 州区划分#

有一个显然的状压,设 fS 表示划分完城市集合 S 之后的答案。

fS=Tf(ST)iTwiiSwi

要求 T 中不包含欧拉回路。

显然可以 O(n2n) 预处理 gS=iSwi,要求 S 合法:

fS=Tf(ST)gTgS=1gSTf(ST)gT

然后这是个显然的子集卷积,做完了,O(n22n)

CF838C Future Failure#

考虑先手必胜的充要条件。

实际上,只要 n 为奇数或者本质不同排列为偶数时先手必胜。

n 为奇数时,先手必胜,答案就是 kn

n 为偶数时,令 ai 为第 i 个字符出现次数,i=1kai=n。反面考虑,我们相当于求 (na1 a2 ... ak) 为奇数的方案数。

根据 Lucas 定理

(mn)i=0q(mini)modp

其中 m=i=0qpimin 同理。

显然这里令 p2mi,ni{0,1}。这告诉我们 (na1 a2 ... ak) 为奇数,相当于 ij,ai&aj=0

考虑一个 dp,fi,j 表示前考虑 i 个字符,目前 aij 的方案数。那么有转移方程:

fp,l=i&j=0,i|j=lfp1,i1j!

这东西显然是个子集卷积,预处理 g|i|,i=1i! 的子集和,暴力O(knlog2n)

然后你死了,最大的点跑了 13 秒,而且空间爆了。考虑优化。

我们考虑指数生成函数暴力 exp 取 ln 然后就做完了。

其实每次转移的 g 都是相同的,这让我们想到了快速幂。

借用快速幂的思想,省略每次重复计算 fg 的若干次,复杂度 O(nlog2nlogk)

挺卡常,但这总比多项式好吧。

组合计数#

斯特林数#

普通幂转下降幂:

nm=i=0m{mi}ni_

Luogu 2791 幼儿园篮球题#

虽然我们家哥哥的房塌了……但这不影响我们卷题啊!

考虑枚举选出来 i没气的篮球,那么答案可以表示成:

ans=1(nk)i=0k(mi)(nmki)iL

注意到这里的组合数 (nm)n<m 或者 m<0 时无意义,直接当成 0 即可。

考虑普通幂转下降幂:

iL=j=0L{Lj}ij_

带入原式有:

ans=1(mk)i=0k(mi)(nmki)j=0L{Lj}ij_=1(mk)j=0L{Lj}i=0k(mi)(nmki)ij_

根据经典组合恒等式:

(mi)ij_=m!i!(mi)!i!(ij)!=m!(mi)!(ij)!=(mj)!(mi)!(ij)!m!(mj)!=(mjij)mj_

代入原式得:

ans=1(mk)j=0L{Lj}i=0k(nmki)(mjij)mj_=1(mk)j=0L{Lj}mj_i=0k(nmki)(mjij)=1(mk)j=0L{Lj}mj_(njkj)

第三步运用了范德蒙德卷积

于是我们只需要求出第 L 行的斯特林数值,就可以通过 O(N) 预处理阶乘及其逆元,对于每个询问 O(L) 得出答案。

这是个经典 trick,通过二项式反演以及 NTT 可以 O(LlogL)求出,可以看 P5395 第二类斯特林数·行,这里不多赘述。

总复杂度 O(N+L(logL+q))

posted @   Arghariza  阅读(111)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
主题色彩