数论
万里长征/fendou,笔者没有接受过系统的学习,有笔误希望能指出/kk。还没填完坑。
upd 2025.11.14 改了 Latex。
补了单位根的性质。
oiwiki-数学符号表
泰勒展开
泰勒展开用于将一些函数以多项式近似表示,可以理解为不断减小多项式与函数的误差。
若想要两函数相同,只需要在某一点使得两函数的任意阶导数均相同即可。
假设用多项式 \(F(x)=\sum_{n\ge 0} f_n(x-x_0)^n\) 来表示函数 \(G(x)\),其中 \(G(x_0)\) 的值是已知的。
假设需要使 \(F(x),G(x)\) 在 \(x_0\) 处的任意阶导数均相同,即 \(x=x_0\) 代入(此处假设 \(G(x)\) 可以无限求导):
\(F(x_0)=\sum_{n\ge 0}f_n\cdot 0^n\)
考虑根据上述的等式将 \(F(x_0)\) 表示出来。
先将 \(F(x_0)\) 每次求导后的结果表示出来。
首先知道 \((x^n)'=nx^{n-1}\):
证明
\[(x^n)'=\lim_{\vartriangle x\to 0} \frac{(x+\vartriangle x)^n-x^n}{\vartriangle x}\\ =\lim_{\vartriangle x\to 0}\frac{\sum_{i=0}^n {n\choose i}x^i(\vartriangle x)^{n-i}-x^n}{\vartriangle x}\\ =\lim_{\vartriangle x\to 0}\frac{\sum_{i=0}^{n-1}{n\choose i}x^i(\vartriangle x)^{n-i}}{\vartriangle x}\\ =\lim_{\vartriangle x\to 0}\sum_{i=0}^{n-1}{n\choose i}x^i(\vartriangle x)^{n-i-1}\]发现只有当 \(n-i-1=0\),即 \(i=n-1\) 时值才有贡献:
\((x^n)'=nx^{n-1}\)
观察发现 \(F^{(n)}(x)=\sum_{i\ge n}i^{\underline n}f_i\cdot 0^{n-i}\)。
其中 \(i^{\underline n}\) 是下降幂,表示 \(\frac{i!}{(i-n)!}\)。
发现只有 \(n-i=0\) 的项才有值,即:
于是得到了 \(F(x)\) 每一项系数的值,代入回原式。
\(F(x)=G(x)=G(x_0)+G'(x_0)(x-x_0)+\frac{G''(x_0)}{2}(x-x_0)^2+\cdots +\frac{{G^{(\infty)}(x_0)}}{\infty!}(x-x_0)^\infty\)
若能使前 \(n\) 阶导数相同,则:
\(F(x)=G(x)=G(x_0)+G'(x_0)(x-x_0)+\frac{G''(x_0)}{2}(x-x_0)^2+\cdots+\frac{G^{(n)}(x_0)}{n!}(x-x_0)^n+R_n(x)\)
其中 \(R_n(x)\) 是余项,表示展开式与原函数的误差,是比 \((x-x_0)^n\) 高阶的无穷小,有两种常见形式:佩亚诺余项,拉格朗日余项。
这就是泰勒展开式。
麦克劳林公式
若 \(x_0=0\),即:
\(F(x)=G(0)+G'(0)x+\frac{G''(0)}{2}x^2+\cdots+\frac{G^{(n)}(0)}{n!}x^n+R_n(x)\)
就是麦克劳林展开式,是泰勒展开式的一种特殊情况。
角的弧度制
圆心角为 \(|a|\) 所对弧度为 \(\frac{\Pi |a|}{180^{\circ}}\)。
复数
复数常用 \(z\) 表示。
定义虚数单位 \(i\) 满足 \(i^2=-1\),对于任意实数与虚数均能用 \(z=a+bi(a,b\in\mathbb{R})\) 表示,其中 \(a\) 为实部 \(Re(z)\),\(b\) 为虚部 \(Im(z)\)。
对于 \(z=a+bi\):
所有复数组成复数集。
\(a=0\land b\not=0\),则 \(z\) 为纯虚数。
\(a\not=0\land b\not=0\),则 \(z\) 为虚数。
\(a\not=0\land b=0\),则 \(z\) 为实数。
这几类数集的包含关系如下:

定义复数的运算:
假设 \(z=a+bi,z_1=c+di\)
\(z+z_1=a+c+(b+d)i\)
\(z-z_1=a-c+(b-d)i\)
\(z\cdot z_1=(a+bi)(c+di)\\\hspace{0.85cm}=ac+adi+bci+bdi^2\\\hspace{0.85cm}=ac-bd+(ad+bc)i\)
\(\frac{z}{z1}=\frac{a+bi}{c+di}\\ \hspace{0.43cm}=\frac{(a+bi)(c-di)}{c^2-(di)^2}\\ \hspace{0.43cm}=\frac{ac+bd-(bc-ad)i}{c^2+d^2}\)
因为 \(i^2=-1\),\(bb_1i^2=-bb_1,(b_1i)^2=-b_1^2\)。
将 \(a-bi\) 记作 \(z=a+bi\) 的共轭复数记作 \(\overline z\)。
实数与数轴上的点一一对应,考虑将复数也转换一下,发现对于一个复数由 \(a,b\) 唯一确定,那是不是意味着可以将复数转换到平面直角坐标系上,\(x\) 轴(实轴)表示 \(a\) 的值,\(y\) 轴(虚轴)表示 \(b\) 的值,用坐标 \(Z(a,b)\) 表示 \(z=a+bi\),将这个平面称作复平面,发现每个复数 \(z\) 都对应了复平面上的向量 \(\overrightarrow{OZ}\)。

定义 \(r\) 为复数的模,\(\theta\) 为复数的幅角(正实轴逆时针到所对向量的夹角)。
\(r=\sqrt{a^2+b^2}\)
那么运用三角函数可以得出:
\(z=r\cos \theta+r\sin \theta i=r(\cos \theta+\sin \theta i)\)
这是复数的三角形式。
欧拉公式 & 证明
\(e^{ix}=\cos x+\sin x\cdot i\)
证明:
对 \(e^{ix}\) 泰勒展开。
建立函数 \(f(x)=e^x,g(x)=ix\),则 \(e^{ix}=f(g(x)),(e^{ix})'=f'(g(x))g'(x)\)。
\(f'(x)=\lim_{\vartriangle x\to 0}\frac{e^{x+\vartriangle x}-e^x}{\vartriangle x}=\frac{e^x(e^{\vartriangle x-1})}{\vartriangle x}=\frac{e^x(1+\vartriangle x)^{\frac{1}{\vartriangle x}\cdot \vartriangle x}}{\vartriangle x}=e^x\)
\(g'(x)=\lim_{\vartriangle x\to 0}\frac{(x+\vartriangle x)i-xi}{\vartriangle x}=i\)
\((e^{ix})'=f'(g(x))g'(x)=ie^{ix}\)
则 \((e^{ix})^{(n)}=i^ne^{ix}=(-1)^{\lfloor\frac{n}{2}\rfloor}i^{n-2\cdot\lfloor\frac{n}{2}\rfloor}e^{ix}\)
根据麦克劳林公式:
\(e^{ix}=1+ix-\frac{1}{2!}x^2-\frac{i}{3!}x^3+\cdots\)
\(\cos' x=\lim_{\vartriangle x\to 0}\frac{\cos(x+\vartriangle x)-\cos x}{\vartriangle x}=\frac{\cos x\cos \vartriangle x-\sin x\sin \vartriangle x-\cos x}{\vartriangle x}=\frac{\cos x(\cos \vartriangle x-1)-\sin x\sin \vartriangle x}{\vartriangle x}=-\sin x\)
\(\sin' x=\lim_{\vartriangle x\to 0}\frac{\sin(x+\vartriangle x)-\sin x}{\vartriangle x}=\frac{\sin x\cos \vartriangle x+\sin \vartriangle x\cos x-\sin x}{\vartriangle x}=\frac{\sin x(\cos \vartriangle x-1)+\cos x\sin \vartriangle x}{\vartriangle x}=\cos x\)
\((\cos x+\sin x\cdot i)'=-\sin x+i\cos x\)
\((\cos x+\sin x\cdot i)''=-\cos x-i\sin x\)
\((\cos x+\sin x\cdot i)'''=\sin x-i\cos x\)
\((\cos x+\sin x\cdot i)''''=\cos x+i\sin x\)
\(\cdots\)
\(\cos x+\sin x\cdot i\) 用麦克劳林公式展开:
\(\cos x+\sin x\cdot i=1+ix-\frac{1}{2!}x^2-\frac{i}{3!}x^3+\cdots\)
则 \(e^{ix}=\cos x+\sin x\cdot i\)
根据欧拉公式 \(e^{i\theta}=\cos \theta+\sin \theta i\),有:
\(z=re^{i\theta}\)
用弧度制表示
\(z=re^{i\frac{2\Pi \theta}{360^{\circ}}}\)
就得到了复数的复指数表示。
\(z\cdot z_1=(r\cdot r_1)e^{i(\theta+\theta_1)}\)
于是就得到了复数乘法的几何意义:
模长相乘,幅角相加。
单位根
考虑 \(x^n=1\) 的解。
定义 \(z=a+bi\) 使得 \(z^n=1\)。
在复数部分最后提到了复数乘法的几何意义。
要使 \(z^n=1\) 成立,就是要 \(z^n\) 模长为 1,幅度为 0。
模长相乘,也就是 \(r^n=(\sqrt{a^2+b^2})^n=1\),\(a,b\in\mathbb{R}\),也就是 \(r\ge 0\land r\in\mathbb{R}\),那么显然 \(r=1\),几何意义就是这些解都在复平面的单位圆上。
幅角相加,也就是 \(n\theta=0,0^{\circ}\le \theta<360^{\circ}\)。
也就是 \(\theta=0\) 或是 \((n\theta)\;\mod\;360=0\)。
则 \(\theta=k\frac{360}{n},0\le k<n\)。
也就是有 \(n\) 个解。
从实轴开始逆时针命名为 \(\omega_n^k\),如下图为例。
以 \(x^8=1\) 为例,\(8\) 个根如上图分布在复平面的单位圆上(单位圆的 \(8\) 等分点),其中把 \(x=1\) 的解记为 \(\omega_n^0\),逆时针依次命名为 \(\omega_n^k\;,\;k={0,1,2,\cdots,n-1}\)。

根据上文可以得到 \(\omega_n^k=e^{ik\frac{360}{n}}\),用弧度制表示 \(\omega_n^k=e^{i\frac{2\Pi k}{n}}=\cos \frac{2\Pi k}{n}+\sin \frac{2\Pi k}{n}i\)。
根据上文所述可以得到几个性质:
\(\omega_n^{k+n}=\omega_n^k\)
单位根具有周期性,相当于在单位圆上转了一周。
\(\omega_{2n}^{k+n}=-\omega_{2n}^k\)
相当于转半圈到关于原点对称的解。
\(\sum_{k=0}^{2n-1} \omega_{2n}^k=0\)
由图可知,两两抵消。
\(\sum_{k=0}^{n-1} \omega_{n}^k=0\)
\(n\) 次单位根 \(\omega_{n}^{0},\omega_{n}^{1}\cdots\) 实际为等比数列,公比为 \(\omega_{n}^1\),根据 \(n\) 次单位根的周期性,用等比数列求和公式 \(\sum_{k=0}^{n-1} \omega_{n}^k=\frac{\omega_{n}^0-\omega_{n}^0}{\omega_{n}^1-1}=0\)。
\(\sum_{k=0}^{n-1}(\omega_{n}^k)^p=n\cdot [n|p]\)
实际上也是等比数列。
\(\sum_{k=0}^{n-1}(\omega_{n}^k)^p=\frac{(\omega_{n}^{n})^p-\omega_{n}^0}{\omega_{n}^p-1}=0\)
当 \(n|p\) 时,该式分母为 0,无法用等比数列求和公式,但显然结果为 \(n\)。
数论
数论分块 (整除分块)
数论分块解决形如求 \(\sum\limits_{i=1}^{n} \lfloor\frac{x}{a_i}\rfloor\) 的问题。
因为有下取整,发现对 \(a\) 数组排序后,会出现多段 \(i \in [l,r] \; \lfloor\frac{x}{a_i}\rfloor\) 的结果相等,考虑对于每一段整体处理。
对于结果 \(a_l\) 作为左端点进行分段,该段右端点 \(a_r\) 的值应满足 \(a_r \le \lfloor {\frac{n}{\lfloor \frac{n}{a_l}\rfloor} } \rfloor\)。而 \(a_r\) 可以通过二分快速找到。很显然 \(\lfloor\frac{x}{a_i}\rfloor\) 仅有 \(2\sqrt x\) 种取值,则数论分块的时间复杂度为 \(O(\sqrt x)\)。
向上取整
形如求 \(\sum\limits_{i=1}^{n} \lceil\frac{x}{a_i}\rceil\) 的问题。
\(\lfloor\frac{x-1}{a_i}\rfloor+1=\lceil\frac{x}{a_i}\rceil\) 则对于 \(a_l\) 作为左端点分段,右端点 \(a_r \le \lfloor {\frac{n-1}{\lfloor \frac{n-1}{a_l}\rfloor} } \rfloor\)。
欧拉函数
欧拉函数 \(\varphi(x)=\sum\limits_{i=1}^{x} [\gcd(i,x)=1],\varphi(1)=1\)
欧拉函数是积性函数,即对于 \(\gcd(x,y)=1,\varphi(xy)=\varphi(x)\varphi(y)\)。
很显然,对于质数 \(p\),\(\varphi(p)=p-1\)。
求 \(\varphi(x)\),根据唯一分解定理,\(x=p_{1}^{k_1}p_{2}^{k_2}...p_{n}^{k_n}\)。对于质数 \(p,\varphi(p^k)=p^{k-1}(p-1)\),即除了 \(p\) 的倍数均与 \(p^k\) 互质。
由此,我们可以求出
则对于任意质数 \(p^k\),\(\varphi(p^k)=p^k\frac{p-1}{p}=p^k-p^{k-1}\)。
还有性质 \(n=\sum_{d|n}\varphi(d)\)。
证明
\[\forall (ij=n,\gcd(i,j)=1),\sum_{i|x}\varphi(i)\sum_{j|y}\varphi(j) \\=\sum_{i|x}\sum_{j|y}\varphi(i)\varphi(j)\]因为 \(x,y\) 互质,则显然 \(i,j\) 没有公共因子。
\[\sum_{i|x}\sum_{j|y}\varphi(i)\varphi(j) \\=\sum_{i|x}\sum_{j|y}\varphi(ij) \\=\sum_{i|xy}\varphi(i) \\=\sum_{i|n}\varphi(i)\]所以设 \(f(n)=\sum_{d|n}\varphi(d)\),则 \(f\) 为积性函数。
对 \(n\) 质因数分解 \(n=p_1^{k_1}p_2^{k_2}p_3^{k_3}\cdots\)。
则 \(f(n)=f(p_1^{k_1})f(p_2^{k_2})\cdots \\=(\varphi(1)+\varphi(p_1)+\varphi(p_1^2)+\cdots+\varphi(p_1^{k_1}))\cdot(\varphi(1)+\varphi(p_2)+\varphi(p_2^2)+\cdots+\varphi(p_2^{k_2}))\cdots \\=(1+(p_1-1)+(p_1^2-p_1)+(p_1^3-p_1^2)+\cdots+(p_1^{k_1}-p_1^{k_1-1}))\cdot(1+(p_2-1)+(p_2^2-p_2)+\cdots+(p_2^{k_2}-p_2^{k_2-1})) \\=p_1^{k_1}\cdot p_2^{k_2}\cdots \\=n \)
筛法求欧拉函数
假设要求出 \(\varphi(1)\) ~ \(\varphi(n)\),可以用筛法求欧拉函数值。
发现线性筛中每个合数都会被其最小的质因子所筛掉,那么假设其最小质因子为 \(p\),设 \(a=\frac{n}{p}\)。
1.\(a\mod p = 0\),此时 \(a\) 包含了 \(n\) 的所有质因子,那么此时 \(\varphi(n)=p\times a\times \prod_{i=1}^{n} \frac{p_i-1}{p_i}=p \; \varphi(a)\)。
\(n=ap\),则 \(n\) 的质因子集合 \(P_n\) 即为 \(P_a\cup P_p\) 而 \(a\mod p=0\),则 \(P_p\subseteq P_a\),则 \(P_n=P_a\)。
2.\(a \mod p \neq 0\),此时 \(p\) 与 \(a\) 显然互质,那么 \(\varphi(n)=\varphi(p)\varphi(a)\)
P2303
给定 \(n\),求 \(\sum_{i=1}^n \gcd(i,n)\)。
时间复杂度 \(O(\sqrt{n})\)。
线性同余方程
求解形如 \(ax \equiv b\pmod n\) 的线性同余方程(\(a\) , \(b\) , \(n\) 为给定整数,在 \([0,n-1]\) 中求解 \(x\))。
将原方程改写为 \(ax+ny=b\),显然此方程有解的条
件为 \(\gcd(a,n)\mid b\)。
同余方程中解的情况
同余方程 \(ax\equiv b\pmod n\)
1.对于 \(\gcd(a,n) = 1\)
此时可以将两边同时乘上 \(a\) 模 \(n\) 意义下的逆元,得到 \(x \equiv ba^{-1}\pmod n\),此时有唯一解。
证明解唯一
假设有两个解分别为 \(x_1,x_2\),则
\[ax_1 \equiv b\pmod n\\ax_2 \equiv b\pmod n \]即
\[ax_1 \equiv ax_2\pmod n \]两边同减 \(a \cdot x_2\) 得
\[a(x_1-x_2)\equiv 0\pmod n \]由于 \(a,n\) 互质,则上述式子成立当且仅当 \(x_1-x_2\equiv 0\pmod n\)。即 \(x_1 \equiv x_2\pmod n\)。由于\(x_1,x_2 \in [0,n-1]\),则 \(x_1=x_2\),得证。
2.\(\gcd(a,n) \neq 1\)
此时,若 \(\gcd(a,n)\nmid b\),则方程无解。
否则,将方程两边同除 \(\gcd(a,n)\),得
此时,\(\gcd(\frac{a}{\gcd(a,n)},\frac{n}{\gcd(a,n)})=1\) 可以根据情况 1,求解此方程的解 \(x_0\),不难发现 \(x_0\) 也是原始方程的解,但不是原始方程的唯一解。
原始方程共有 \(\gcd(a,n)\) 个解,为 \(x_0+i\gcd(a,n),i \in [0,\gcd(a,n)-1]\)。
证明有 \(\gcd(a,n)\) 个解
根据上述求解过程。
\[ax \equiv b\pmod n \]\[\frac{a}{\gcd(a,n)}x \equiv \frac{b}{\gcd(a,n)}\pmod {\frac{n}{\gcd(a,n)}} \]可以改写为
\[x \equiv \frac{b}{\gcd(a,n)}\cdot (\frac{a}{\gcd(a,n)})^{-1}\pmod {\frac{n}{\gcd(a,n)}} \]即
\[x=[(\frac{b}{\gcd(a,n)}\cdot (\frac{a}{\gcd(a,n)})^{-1} \mod\;\frac{n}{\gcd(a,n)})+k\cdot \frac{n}{\gcd(a,n)}]\pmod n \]考虑将 \(k\) 表示为 \(k=p\cdot \gcd(a,n)+w,w\in[0,\gcd(a,n)-1]\),则方程可表示为:
\[x\equiv[\frac{b}{\gcd(a,n)}\cdot (\frac{a}{\gcd(a,n)})^{-1}\mod\;\frac{n}{\gcd(a,n)})+p\cdot n+w\cdot \frac{n}{\gcd(a,n)}]\pmod n,w\in[0,\gcd(a,n)-1] \]\(w\) 有 \(\gcd(a,n)\) 种取值,故有 \(\gcd(a,n)\) 个解。
综上,同余方程有 \(\gcd(a,n)\) 或 0 个解。
扩展欧几里得(exgcd)
众所周知,
证明
设 \(d\) 为 \(a,b\) 的任意公因数,\(a=nd,b=md\),则 \(a\%b=d(n-m\cdot p)\)
于是得到当\(a\%b\not= 0\) 时 \(a\% b,b\) 的公因子集合等于 \(a,b\) 的公因子集合,显然 \(\gcd(a,b)=\gcd(b,a\% b)\)。
假如按照上述定理转化,在某次操作中发现 \(a^{'}\%b^{'}=0\),那么此时 \(b^{'}\) 即为 \(\gcd(a,b)\)。
证明
上文证明 \(a^{'},b^{'}\) 的公因子集合等于 \(a,b\) 的公因子集合,此时 \(a^{'}\% b^{'}=0\),则 \(b^{'}\) 为 \(a^{'}\) 的因子,显然 \(b^{'}=\gcd(a^{'},b^{'})=\gcd(a,b)\)。
裴蜀定理得
扩展欧几里得用来求解不定方程的特解。
对于同余方程
将方程改写为
上文提到过有解则 \(\gcd(a,n)\mid b\),考虑求出一组特解 \(x_0,y_0\) 使得 \(ax_0+ny_0=\gcd(a,n)\),根据裴蜀定理这组特解一定存在,则 \(x=\frac{x_0\cdot b}{\gcd(a,n)}\)。
根据
可以写出求解 \(\gcd(a,b)\) 的代码:
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
当递归终止时 \(a=\gcd(a,b),b=0\),此时 \(a\times1+b\times0=\gcd(a,b)\),但是此时 \(a,b\) 不等于原来的 \(a,b\) 那么要求出对于原来的 \(a,b\) 的特解可以考虑递归的每一层用下一层得出的 \(x_0,y_0\) 推出本层得 \(x_0,y_0\),推回原来的 \(a,b\) 的 \(x_0,y_0\)。
考虑对于一层 \(a,b\) 的 \(x,y\),与下一层 \(a^{'},b^{'}\) 的 \(x^{'},y^{'}\) 的关系。
可以发现,
带入得
所以 \(x=y^{'},y=x^{'}-\lfloor\frac{a}{b}\rfloor\cdot y^{'}\)。
于是我们就求出了使得 \(ax_0+ny_0=\gcd(a,n)\) 的特解。
[代码示例]
int x,y;
void exgcd(int a,int b){
if(!b){x=1,y=0;return;}
exgcd(b,a%b);int t=x;
x=y,y=t-a/b*y;return;
}
求出了特解后就因题而异了。
乘法逆元
若 \(ax\equiv 1(mod\;b)\) 则称 \(x\) 为 \(a\) 模 \(b\) 意义下的逆元,记作 \(a^{-1}\)。乘法逆元用于带取模的除法,仅当 \(\gcd(a,b)=1\) \(a\) 在模 \(b\) 意义下才有逆元。
求逆元
1.快速幂求逆元
若 \(b\) 为质数,则根据费马小定理得
用快速幂求 \(a^{b-2}\) 即可。
费马小定理:对于素数 \(p,\gcd(a,p)=1\),则 \(a^{p-1}\equiv 1\pmod p\)。
证明
引理: \(\prod_{i=1}^{p-1}i\equiv \prod_{i=1}^{p-1}a\cdot i\pmod p\)。
首先 \(i\in[1,p-1]a\cdot i\pmod p\) 互不相同。
假设 \(a\cdot x\equiv a\cdot y\equiv k\pmod p,x,y\in [1,p-1],x\not=y\)。
那么 \(a\cdot x\),\(a\cdot y\) 必定可以表示为 \(a\cdot m+k\),\(a\cdot m_1+k,m\not=m_1\)。
\[a\cdot m+k\equiv a\cdot m_1+k\equiv k\pmod p \\a\cdot m\equiv a\cdot m_1\equiv 0\pmod p\]因为 \(\gcd(a,p)=1\) 所以满足上式时当且仅当 \(m|p,m_1|p\),因为 \(m\not=m_1\),所以 \(m\) 与 \(m_1\) 至少相差 \(p\),而 \(x=m+\frac{k}{a},y=m_1+\frac{k}{a},x,y\in [1,p-1]\) 所以不存在这样的 \(x,y\),证毕。
因为模 \(p\) 意义下值域为 \([0,p-1]\),而 \(i\in[1,p-1]a\cdot i\pmod p\) 共有 \(p\) 个值,所以 \(A=\{x\in[1,p-1]|x\;\mod p\},A1=\{x\in[1,p]|a\cdot x\mod\;p\},A=A1\)。
2.扩展欧几里得求逆元
等同于求解同余方程。
3.求任意数的逆元。
记 \(s_i=\prod_{j=1}^{i} a_j\)。
一开始 \(s_n\) 为 \(n\) 个数的积,\(s_n^{-1}\) 为 \(n\) 个数逆元之积,乘上 \(a_n\) 就可以得到 \(s_{n-1}^{-1}\) 此时 \(s_{n-1}^{-1}\cdot s_n\) 即为 \(a_n\) 的逆元,以此类推,时间复杂度 \(O(n)\)。
中国剩余定理(CRT)
CRT 用来求解以下方程组:
其中 \(n_i\) 两两互质。
设 \(N=\prod n,\;m_i=\frac{N}{n_i}\)。
根据定义可知 \(\gcd(m_i,n_i)=1\)。
\(\;m_i^{-1}\) 表示 \(m_i\) 在模 \(n_i\) 意义下的逆元。
则方程在 \(\mod\;N\) 意义下一解 \(ans=\sum a_im_im_i^{-1}\pmod N\)。
证明
\(a_im_im_i^{-1}\equiv a_i\pmod {n_i}\)
根据定义可知 \(n_j|m_i\),即:
\(a_im_im_i^{-1}\equiv 0\pmod {n_j}\;,\;(j\not=i)\)
则 \(a_im_im_i^{-1}\) 仅对模 \(n_i\) 的结果做贡献使 \(ans\equiv a_i\pmod {n_i}\) 得证。
EXCRT
若 \(n_i\) 不满足两两互质:
合并 \(n-1\) 次,每次合并对于两个方程 \(x\equiv a_1\pmod {n_1},\;x\equiv a_2\pmod {n_2}\)。
把第一个式子变为不定方程的形式。
于是只要求出新的不定方程的解,该解必定同时满足原来两同余方程 ,假设 \(x^{\prime}\) 为该不定方程最小正整数解,则其所有解都可以表示为 \(x^{\prime}+p\cdot lcm(n_1,n_2)\),也就是 \(x\equiv x^{\prime}\pmod {lcm(n_1,n_2)}\) 于是就将两个方程合并了,合并到最后的 \(x^{\prime}\) 即为答案。
莫比乌斯反演
解决问题:
若两个函数 \(f(n)=\underset{d|n}{\sum}g(d)\) 那么 \(g(n)=\underset{d|n}{\sum}\mu(d)f(\frac{n}{d})\),其中 \(\mu\) 是莫比乌斯函数,解决 Dirichlet 卷积的函数反演问题(证明见 oiwiki 下仅介绍莫比乌斯函数)。
定义莫比乌斯函数
\(n\) 含平方因子指质因数分解后 \(x=\prod p_i^{c_i}\) 当存在 \(c_i>1\) 时即为出现平方因子 \(\mu(x)=0\),否则 \(k=\sum [c_i=1],\mu(x)=(-1)^k\)。
\(\underset{d|n}{\sum} \mu(d)=[n=1]\)
证明
因为存在平方因子则 \(\mu(d)=0\),那么说明对这个式子有贡献的 \(d=\prod p_i^{c_i}\),必须满足 \(c_i\in\{0,1\}\)。若只改变 \(c_i\) 的取值,那么 \(\mu(d)\) 会变成相反数(因为 \(k\to k\pm 1\)),所以对于任意 \(n\not= 1\),该式值恒为 0。
\([\gcd(i,j)=1]=\sum_{d|\gcd(i,j)}\mu(d)\)
这个式子就是让上面一个式子的 \(n=\gcd(i,j)\)。
P2522
给定 \(a,b,c,d\),求 \(\sum_{i=a}^b\sum_{i=c}^d [\gcd(i,j)=k]\)。\(a,b,c,d\leq 5\times 10^4\)。
容斥,
\(ans=\sum_{i=1}^b\sum_{j=k}^d [\gcd(i,j)=k]-\sum_{i=1}^b\sum_{j=1}^{c-1} [\gcd(i,j)=k]-\sum_{i=1}^{a-1}\sum_{j=1}^d [\gcd(i,j)=k]+\sum_{i=1}^{a-1}\sum_{j=1}^{c-1} [\gcd(i,j)=k]\)。
四部分求法是相同的,以第一项举例。
四部分用数论分块 \(O(\sqrt{n})\) 求即可。
P1829
给定 \(n,m\),求 \(\sum_{i=1}^{n}\sum_{j=1}^{m}\text{lcm}(i,j)\)。\(n,m\leq 10^7\)。
记 \(N=\min(n,m)\)。
首先知道 \(\text{lcm(a,b)}=\frac{ab}{\gcd(a,b)}\)。
设 \(g(x,y)=\sum_{k=1}^{N}\mu(k)k^2\frac{(1+\lfloor\frac{x}{k}\rfloor)\lfloor\frac{x}{k}\rfloor}{2}\cdot\frac{(1+\lfloor\frac{y}{k}\rfloor)\lfloor\frac{y}{k}\rfloor}{2}\),
则 \(ans=\sum_{d=1}^Nd\cdot g(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)\)。
两层数论分块求解即可。
杜教筛
杜教筛可以在小于 \(O(n)\) 的复杂度内求出数论函数的前缀和。
首先知道狄利克雷卷积 \((f\cdot g)(n)=\sum_{i|n}f(i)g(\frac{n}{i})\)。
定义 \(sum(n)=\sum_{i=1}^n g(i)\)。
则
推到这一步启发我们若要求数论函数 \(g\) 的前缀和 \(sum(n)\),只需要找到能在优秀复杂度内计算的数论函数 \(k=f\cdot g\) 即可,而 \(\sum_{j=2}^nf(j)sum(\lfloor \frac{n}{j}\rfloor)\) 则可以用整除分块递归 + 记忆化求解,具体细节参照 【模板】杜教筛 中的题解或下文代码。
时间复杂度 \(O(n^{\frac{3}{4}})\),证明见 oiwiki。
杜教筛的重点即为找到函数 \(k\),举模板中的两个例子。
介绍几个数论函数:
\(\epsilon(n)=[n=1]\)。
容易发现任意函数 \(f\) 与 \(\epsilon\) 的狄利克雷卷积仍为 \(f\)。
\(Id(n)=n\)。
\(I(n)=1\)。
- 求 \(sum(n)=\sum_{i=1}^n\varphi(i)\)。
上文中有证明欧拉函数的性质 \(n=\sum_{d|n}\varphi(d)\)。
也就是说 \((\varphi\cdot I)(n)=n=Id(n)\)。
所以函数 \(f\) 取 \(I\),\(k\) 取 \(Id\)即可。
具体代码如下,其中 \(p\) 为预处理得出的 \(n\le 5\times 10^6\) 范围内的 \(sum(n)\)。
[代码示例]
unordered_map<int,int>ps;
inline int P(int x){
if(x<=5e6)return p[x];
if(ps.count(x))return ps[x];
int l=2,r=2,res=x*(x+1)/2;
while(l<=x)r=x/(x/l),res-=(r-l+1)*P(x/r),l=r+1;
return ps[x]=res;
}
- 求 \(sum(n)=\sum_{i=1}^n\mu(i)\)。
上文也有证明 \(\sum_{d|n}\mu(d)=[d=1]\)。
即 \((\mu\cdot I)(n)=[n=1]=\epsilon(n)\)。
则 \(f\) 取 \(I\),\(k\) 取 \(\epsilon\) 即可。
代码与求欧拉函数前缀和基本相同。
多项式
快速傅里叶变换 FFT
\([x^n]F(x)\) 表示多项式 \(F(x)\) 的 \(x^n\) 项的系数。
两个\(n\) 次多项式 \(F(x)=\sum_{i=0}^{n} f_ix^i\),\(m\) 次多项式 \(G(x)=\sum_{i=0}^m g_ix^i\) 的卷积为:
\(A(x)=F(x)\cdot G(x)\\ =\sum_{i=0}^n f_i\sum_{j=0}^m g_jx^{i+j}\\ =\sum_{i=0}^{n+m}x^i\sum_{j=0}^{i}f_ig^{i-j}\)
暴力求需要 \(O(n^2)\),而快速傅里叶变换可以将时间复杂度降至 \(O(n\log n)\)。
先看弧度制、复数、单位根。
首先因为 \(F(x)\cdot G(x)=(F\cdot G)(x)\),而一个 \(n\) 次多项式可以由 \(n+1\) 个点确定且点值表示下多项式乘法是 \(O(n)\) 的。
这启发我们得到
\((x_0,F(x_0)),(x_1,F(x_1)),(x_2,F(x_2)),\cdots,(x_{n+m+1},F(x_{n+m+1}))\)。
\((x_0,G(x_0)),(x_1,G(x_1)),(x_2,G(x_2)),\cdots,(x_{n+m+1},G(x_{n+m+1}))\)
于是就可以得到 \(A(x)\) 的点值表示,再推出 \(A(x)\) 的系数表示。
但 FFT 运用的就是这个思想。
但这样还是 \(O(n^2)\),逐个代入求值再推 \(A(x)\)。
而 FFT 通过代入单位复根,运用单位复根的性质分治将这个过程降至 \(O(n\log n)\)。
此处假设 \(2|(n+1)\),也就是多项式有偶数项。
以 \(F(x)\) 为例:
奇偶分组得到:
此时降奇数项部分提个 \(x\) 得到:
代入单位复根,要得到点值表示需要 \(n+1\) 个点,于是代入 \(\omega_{n+1}^k,k\in[0,n]\):
因为 \(\omega_{n+1}^k=-\omega_{n+1}^{k-\frac{n+1}{2}}\),\((\frac{n+1}{2}\le k\le n)\)则
也就是只要求出 \(F_0(\omega_{\frac{n+1}{2}}^k),F_1(\omega_{\frac{n+1}{2}}^k),k\in[0,\frac{n+1}{2}-1]\) 就可以求出 \(F(\omega_{n+1}^k),k\in[0,n]\)。
于是就成了两个子问题且规模都缩小到了原问题的 \(\frac{1}{2}\)。
初见端倪,可以分治 \(O(n\log n)\) 求出点值表示了。
为了简单实现,将 \(F(x)\) 补上系数为 0 的高次项使得 \(n+1\) 为 2 的次幂,这样就可以保证递归到每层多项式都有偶数项。
现在做到 \(O(n\log n)\) 求出 \(F(x),G(x),A(x)\) 的点值表示了,要怎么推出 \(A(x)\) 的系数?
快速傅里叶逆变换
快速傅里叶变换是将系数表示转为点值表示,那么快速傅里叶逆变换就是将点值表示转为系数表示。
感觉这个东西很神!
假设多项式 \(A(x)=\sum_{i=0}^{n+m}a_ix^i\)
设多项式
那么想要得到 \(a_k\),就需要使得所有 \(a_j\;,\;j\not=k\) 的系数为 0。
即如何能使除 \(\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^kx^i\) 外所有 \(\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^jx^i=0\)。
想到单位根有一性质为 \(\sum_{k=0}^{n-1}(\omega_{n}^k)^p=n\cdot [n|p]\)。
结合上面所说的性质,\(n|p\) 不妨最终 \((\omega_{n+m+1}^i)^{k'},k'=0\),将 \(x=(\omega_{n+m+1}^{-k})\) 带入即可。
\(\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^k(\omega_{n+m+1}^{-i})^k=\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^k(\omega_{n+m+1}^{i})^{-k}=\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^0=n+m+1\)
对于 \(j\not=k\),\(\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^j(\omega_{n+m+1}^{-i})^k=\sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^{j-k}\)
\(\because j-k\not= 0\)
\(\therefore \sum_{i=0}^{n+m}(\omega_{n+m+1}^i)^{j-k}=0\)
\(R(\omega_{n+m+1}^{-k})=(n+m+1)a_k\)
\(a_k=\frac{R(\omega_{n+m+1}^{-k})}{n+m+1}\)
正逆变换求点值带入的值仅正负相反,代码相同,仅传入一个值控制带入值的正负即可。
[代码示例]
仅展示主要部分代码
const double P=acos(-1);//P即为 \Pi
const int N=4e6+5;
struct cplx{
double a,b;
cplx operator+(const cplx y){return cplx{a+y.a,b+y.b};}
cplx operator-(const cplx y){return cplx{a-y.a,b-y.b};}
cplx operator*(const cplx y){return cplx{a*y.a-b*y.b,a*y.b+b*y.a};}
}f[N],g[N],a[N],t[N];
void FFT(cplx *f,int n,int op){
if(n==1)return;
for(int i=0;i<n;i++)t[i]=f[i];
for(int i=0;i<n;i++)f[!(i&1)?i/2:(n+i)/2]=t[i];
FFT(f,n/2,op),FFT(f+n/2,n/2,op);
cplx l=cplx{cos(2*P/n),sin(2*P/n)*op},w=cplx{1,0};
for(int i=0;i<n;i++)t[i]=f[i];
for(int i=0;i<n/2;w=w*l,i++)
f[i]=t[i]+w*t[i+n/2],f[i+n/2]=t[i]-w*t[i+n/2];
}
应用
tip:对于 \(\sum_{i=0}^n\sum_{j=0}^{n-i}f_{i+j}g_j\) 可以将 \(f_{n-i}=f_i\) 反转,则原式变为 \(\sum_{i=0}^n\sum_{j=0}^{n-i}f_{n-i-j}g_j\),此时变为卷积形式。
P3338
给定 \(q_1,q_2,\cdots,q_n\),求 \(i\in[1,n]ans_i=\frac{\sum_{j=1}^{i-1}\frac{q_i\cdot q_j}{(i-j)^2}-\sum_{j=i+1}^{n}\frac{q_i\cdot q_j}{(i-j)^2}}{q_i}\)。
\(ans_i=\frac{\sum_{j=1}^{i-1}\frac{q_i\cdot q_j}{(i-j)^2}-\sum_{j=i+1}^{n}\frac{q_i\cdot q_j}{(i-j)^2}}{q_i}=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^{n}\frac{q_j}{(i-j)^2}\)
若 \(i=j\) 时,\(\frac{q_j}{(i-j)^2}=q_i\),当原式两项 \(j\) 均能等于 \(i\) 时对 \(ans_i\) 多出的贡献分别为 \(q_i,-q_i\),故对 \(ans_i\) 无影响。
\(ans_i=\sum_{j=1}^{i}\frac{q_j}{(i-j)^2}-\sum_{j=i}^{n}\frac{q_j}{(i-j)^2}\)
考虑两项分开处理。
设 \(F(x)=\sum_{i=1}^n q_ix^i,G(x)=\sum_{i=1}^n\frac{x^i}{i^2}\)
对于 \(\sum_{j=1}^{i}\frac{q_j}{(i-j)^2}\)。
那么 \(\sum_{j=1}^{i}\frac{q_j}{(i-j)^2}=[x^i]F(x)G(x)\),可以用 FFT \(O(n\log n)\) 求出。
对于 \(\sum_{j=i}^{n}\frac{q_j}{(i-j)^2}\)。
此时 \(\sum_{j=i}^{n}\frac{q_j}{(i-j)^2}=\sum_{j=i}^n f_{j}g_{j-i}=\sum_{j=1}^{n-i}f_{i+j}g_j\)。
上面提到的小技巧可以将其转为卷积形式。
\(f_{n-i}=f_i\),则
\(\sum_{j=1}^{n-i}f_{i+j}g_j\) 变为 \(\sum_{j=1}^{n-i}f_{n-i-j}g_j\) 就成为卷积形式,然后 FFT \(O(n\log n)\) 解决即可。
生成函数
生成函数可以将部分递推式转化为多项式的卷积形式后用 FFT 做到 \(O(n\log n)\) 降低时间复杂度或者直接用封闭形式大力乘在一起得到一个可以优秀处理的东东。
普通生成函数 OGF
普通生成函数定义为形式幂级数的形式如下:
\(F(x)=\sum_{n\ge 0} f_nx^n\)
可以把生成函数看作一个序列, \(x^n\) 看作是一个标号,表示序列第 \(n\) 位上值为 \(f_n\)。
定义运算规则:
封闭形式
运算过程中有时会把生成函数写作封闭形式。
如 \(F(x)=\sum_{n\ge 0}x^n\) 发现 \(xF(x)+1=F(x)\) 那么 \(F(x)=\frac{1}{1-x}\)。
感觉不太对啊,为什么一个多项式可以表示成这样一个分式的形式?
还记得麦克劳林展开式吗,把 \(F(x)=\frac{1}{1-x}\) 写成麦克劳林展开式。
\(F(x)=F(0)+F'(0)x+\frac{F''(0)}{2}x^2+\cdots+\frac{F^{(n)}(0)}{n!}x^n\)
前文有提到 \((x^n)'=nx^{n-1}\)(证明在泰勒展开部分亦有记载),下文用来求导 \(H(x)\) 的导数,且知道链式法有 \(F(x)=H(G(x))\),则 \(F'(x)=H'(G(x))G'(x)\)。
设 \(G(x)=1-x\),\(H(x)=x^{-1}\),\(F(x)=H(G(x))\)
\(G'(x)=\lim_{\vartriangle x\to 0}\frac{1-x-\vartriangle x-1+x}{\vartriangle x}=-1\)
\(H'(x)=\lim_{\vartriangle x\to 0}\frac{(x+\vartriangle x)^{-1}-x^{-1}}{\vartriangle x}=\frac{x-x-\vartriangle x}{(x+\vartriangle x)x\vartriangle x}=-x^{-2}\)
\(F'(x)=-\frac{1}{(1-x)^2}\cdot(-1)=(1-x)^{-2}\)
设 \(H_1=x^{-2}\),则 \(F'(x)=H_1(G(x))\)。
\(H_1'=-2x^{-3}\)
\(F''(x)=-2(1-x)^{-3}\cdot (-1)=2(1-x)^{-3}\)
设 \(H_2=2x^{-3}\),\(F''(x)=H_2(G(x))\)。
\(H_2'=-6x^{-4}\)
\(F'''=-6(1-x)^{-4}\cdot -1=6(1-x)^{-4}\)
根据这几项的规律发现 \(F^{(n)}(x)=n!(1-x)^{-n-1}\)
则 \(F^{(n)}(0)=n!\),代入麦克劳林展开式:
\(F(x)=1+x+x^2+x^3+\cdots=\sum_{n\ge 0}=x^n\)
发现展开后与原生成函数完全一致!
证明 \(F^{(n)}(0)\) 为 \(n!\)
考虑用数学归纳法证明 \(F^{(n)}(x)=n!(1-x)^{-n-1}\):
设 \(H_n(x)=n!x^{-n-1}\),则 \(F^{(n)}(x)=H_n(G(x))\)
\(H_n'(x)=-n!(n+1)x^{-n-2}=-(n+1)!x^{-n-2}\)
\(F^{(n+1)}(x)=-(n+1)!(1-x)^{-n-2}\cdot (-1)=(n+1)!(1-x)^{-n-2}\)
证毕。
\(F(x)=2ix^i\) 的封闭形式为 \(\frac{2x}{(1-x)^2}\)。
证明
设 \(G(x)=\sum_{i\ge 0}ix^i\),则 \(F(x)=2G(x)\)。
\(G(x)=\sum_{i\ge 0}ix^i=x\sum_{i\ge 1}ix^{i-1}=x\sum_{i\ge 0}(x^i)'=x(\frac{1}{1-x})'=\frac{x}{(1-x)^2}\)
\(F(x)=2G(x)=\frac{2x}{(1-x)^2}\)
卡特兰数的封闭形式
首先知道卡特兰数的递推式:
\(C_1=1\\ C_n=\sum_{i=1}^{n}C_{i-1}C_{n-i}\;,\;(n\ge 2)\)
写成生成函数:
\(C(x)=\sum_{n\ge 0} C_nx^n\\ \hspace{0.85cm}=1+\sum_{n>1}\sum_{i=1}^{n}C_{i-1}C_{n-i}x^n\\ \hspace{0.85cm}=1+\sum_{i=1}^n\sum_{j=1}^nC_iC_jx^{i+j+1}\\ \hspace{0.85cm}=1+x\sum_{i=1}^nC_ix^i\sum_{j=1}^nC_jx^j\)
很神奇啊,这样 \(\sum_{i=1}^nC_ix^i\) 和 \(\sum_{j=1}^nC_jx^j\) 不都等同于 \(C(x)\) 了么?
\(C(x)=1+xC^2(x)\)
于是得到:
\(xC^2(x)-C(x)+1=0\)
当作一元二次方程求解,得:
\(C(x)=\frac{1\pm \sqrt{1-4x}}{2x}=\frac{(1\pm \sqrt{1-4x})(1\mp \sqrt{1-4x})}{2x(1\mp\sqrt{1-4x})}=\frac{1}{1\mp \sqrt{1-4x}}\)
求到这里难道卡特兰数有两个封闭形式吗?
并非如此,发现展开后当 \(x=0\) 时,\(\frac{1}{1-\sqrt{1-4x}}\) 分母为 0,无法表示原生成函数,故舍去。
则卡特兰数的生成函数封闭形式为 \(\frac{1}{1+\sqrt{1-4x}}\)。
应用:
P10780 食物
对于设 \(a_i\) 为拿了 \(i\) 个的方案数。
先求出每种食物对应 \(a\) 序列的生成函数再相乘后得到新的生成函数,新的生成函数的第 \(n\) 位系数即为答案。
汉堡:
序列形如 \(\langle 1,0,1,0,1,0,\cdots\rangle\)。
\(F(x)=\sum_{n\ge 0} x^{2n}=\frac{1}{1-x^2}\)
可乐 & 土豆片炒肉:
序列形如 \(\langle 1,1,0,0,0,\cdots\rangle\)。
\(F(x)=1+x\)
鸡腿:
序列形如 \(\langle 1,1,1,0,0,0,\cdots\rangle\)。
\(F(x)=1+x+x^2\)
蜜桃多:
序列形如 \(\langle 0,1,0,1,0,1\cdots\rangle\)。
\(F(x)=\sum_{n\ge 0}x^{2n+1}=x\sum_{n\ge 0}x^{2_n}=\frac{x}{1-x^2}\)
鸡块:
序列形如 \(\langle 1,0,0,0,1,0,0,0,1,\cdots\rangle\)。
\(F(x)=\sum_{n\ge 0}x^{4n}=\frac{1}{1-x^4}\)
包子:
序列形如 \(\langle 1,1,1,0,0,0,0,\cdots\rangle\)。
\(F(x)=1+x+x^2+x^3\)
面包:
序列形如 \(\langle 1,0,0,1,0,0,1,\cdots\rangle\)。
\(F(x)=\sum_{n\ge 0}x^{3n}=\frac{1}{1-x^3}\)
相乘化简得 \(\frac{x}{(x-1)^4}=x(x-1)^{-4}\)。
广义二项式定理展开,最终会得到 \(F^{\prime}(x)=\sum_{i\ge 0}{i+3\choose i}x^i=\sum_{i\ge 1}{i+2\choose i-1}x^i\)。
答案就是 \([x^n]F^{\prime}(x)=\frac{n(n+1)(n+2)}{6}\)。
详见原题题解。
P6078 [CEOI 2004] Sweets
首先考虑设计 dp 状态。
设 \(f_{i,j}\) 表示前 \(i\) 中糖吃 \(j\) 个的方案数。
\(f_{i,j}=\sum_{k=0}^{m_i}f_{i-1,j-k}\)
\(j\) 从大往小枚举可以省去第一维:
\(f_{j}=\sum_{k=0}^{m_i}f_{j-k}=\sum_{k=0}^{m_i}f_{j-k}\cdot 1\)
发现如果把 1 看作是第 \(i\) 种糖吃 \(k\) 颗的方案数设为 \(g_k\),那不就是形如 \(f_{j}=\sum_{k=0}^{i}f_kg_{j-k}\),这不就是多项式卷积的形式吗?
于是考虑生成函数,对于第 \(i\) 种糖的生成函数为 \(F_i(x)=\sum_{j=0}^{m_i}x^j\),设 \(G(x)=\prod_{i=0}^{n} F_i(x)\),最后的答案就是 \(\sum_{i=a}^b[x^i]G(x)\),发现这道题就算是用 FFT 也需要 \(O(nm\log m)\) 无法通过,那考虑大力把生成函数乘在一起了。
考虑求 \(F_i(x)\) 的封闭形式,
\(F_i(x)=1+x+x^2+\cdots+x^{m_i}\)
则 \(F_i(x)=xF_i(x)-x^{m_i+1}+1\to F_i(x)=\frac{1-x^{m_i+1}}{1-x}\)
\(G(x)=\prod_{i=0}^n F_i(x)=\frac{\prod_{i=0}^n(1-x^{m_i-1})}{(1-x)^n}\)
推了半天分子部分发现推不出来,发现可以 \(2^n\) 暴力拆开得到每一项的系数与指数(枚举每一项取 \(1\) 或是 \(-x^{m_i+1}\))。于是转战分母部分。
分母非常的二项式定理啊,但是如果先把分子拆开再除显然不太可行,那么就将 \(\frac{\prod_{i=0}^n(1-x^{m_i-1})}{(1-x)^n}\) 转换为 \(\prod_{i=0}^n(1-x^{m_i-1})\cdot (1-x)^{-n}\)。
\(G(x)=\prod_{i=0}^n(1-x^{m_i-1})\cdot (1-x)^{-n}\)
那这个时候就得用指数为负的二项式定理了(在下文组合数学中亦有记载):
\((1-x)^{-n}=\sum_{i=0}^{\infty}(-1)^i{n+i-1\choose n-1}(-x)^{i}\)
把 -1 抵消:
\((1-x)^{-n}=\sum_{i=0}^{\infty}{n+i-1\choose n-1}x^{i}\)
\(G(x)=\prod_{i=0}^n(1-x^{m_i-1})\cdot \sum_{i=0}^{\infty}{n+i-1\choose n-1}x^{i}\)
这样的话暴力拆开分子部分后就可以枚举分母部分的 \(x^i\) 的次数了。
暴力拆 \(\prod_{i=0}^n(1-x^{m_i-1})\) 得到 \(x^k\) 的系数记为 \(c\)。
要被记录到答案中,那么 \(x^k\cdot x^i\) 的指数必须在 \([a,b]\) 中,即 \(a\le k+i\le b\to a-k\le i\le b-k\)。
那么 \(x^k\) 对答案的贡献是 \(c\cdot \sum_{i=a-k}^{b-k} {n+i-1\choose n-1}\)。
但是这样时间复杂度需要 \(O(2^nm)\) 相当不优秀。
根据组合数的递推式 \({n\choose m}={n-1\choose m-1}+{n-1\choose m}\) 可以进一步优化这个式子。
\(\sum_{i=a-k}^{b-k} {n+i-1\choose n-1}={n+a-k-1\choose n-1}+{n+a-k\choose n-1}+\cdots+{n+b-k-1\choose n-1}\\ ={n+b-k \choose n}-{n+a-k-1\choose n}\)
把 \(n+b-k\choose n\) 按递推式不停拆开,就能得到
\({n+b-k\choose n}={n+b-k-1\choose n-1}+{n+b-k-1\choose n}={n+b-k-1\choose n-1}+{n+b-k-2\choose n-1}+{n+b-k-2\choose n}+\cdots\)
得到 \({n+b-k\choose n}=\sum_{i=a-k}^{b-k}{n+i-1\choose n-1}+{n-a-k-1\choose n}\)
则 \(x^k\) 对答案的贡献变为:
\(c\cdot ({n+b-k \choose n}-{n+a-k-1\choose n})\)
\({n+b-k \choose n}=\frac{(n+b-k)^{\underline n}}{n!}\)
\({n+a-k-1\choose n}=\frac{(n+a-k-1)^{\underline n}}{n!}\)
这样时间复杂度就降到 \(O(2^n)\) 了?
发现模数不是质数,无法直接求逆元,有一个小技巧。
知道 \(\forall y|x\;,\;\frac{x}{y}\mod\;p=\frac{x\mod\;yp}{y}\)。
证明
设 \(x=ky\),
则 \(\frac{x}{y}\mod\;p=k\mod\;p\),
\(\frac{x\mod\;yp}{y}=\frac{(k\mod\;p)y}{y}=k\mod\;p\)
\(n\) 很小,可以 \(O(n)\) 计算,将模数 \(p\to pn!\),算完组合数后再除 \(n!\),时间复杂度 \(O(2^nn)\)。
指数生成函数 EGF
指数生成函数定义为形式幂级数的形式如下:
\(\hat F(x)=\sum_{n\ge 0}f_n\frac{x^n}{n!}\)
其中 \(f_n\) 才是生成函数第 \(n\) 项的值,所以第 \(n\) 项的值是 \(n![x^n]F(x)\)。
加法与减法的运算与普通生成函数相同,同项系数加减。
封闭形式
序列 \(\langle 1,1,1,\cdots\rangle\) 的指数生成函数封闭形式为:
\(\hat F(x)=\sum_{n\ge 0} \frac{x^n}{n!}=e^x\)
证明
首先知道 \((x^n)'=nx^{n-1}\)(在泰勒展开部分有证明)。
发现因为 \(\lim_{\vartriangle x\to 0}\) 所以只有 \(n-i-1=0\) 时才有贡献
\[(x^n)'=nx^{n-1} \]将 \(e^x\) 在 \(x=0\) 处泰勒展开。
首先将 \(e\) 写成定义式 \(\lim_{n\to \infty}(1+\frac{1}{n})^n\)。
\[(e^x)'=\lim_{\vartriangle x\to 0}\frac{e^{x+\vartriangle x}-e^x}{\vartriangle x}\\ =e^x\lim_{\vartriangle x\to 0}\frac{e^{\vartriangle x}-1}{\vartriangle x}\\ =e^x\lim_{n\to \infty} \frac{((1+\frac{1}{n})^n)^{\frac{1}{n}}}{\frac{1}{n}}-n\\ =e^x\]发现 \((e^x)'=e^x\)。
\(e^x=e^0+x\cdot e^0+\frac{x^2}{2!}\cdot e^0+\cdots=1+x+\frac{x^2}{2!}+\cdots=\hat F(x)\)
应用:
给定 4 种元素,要求用这 4 种元素组成一个长度为 \(n\) 的序列(\(1\le n\le 8\))每种元素至多用 2 个,求有多少种可能的序列。
首先设计 dp 状态 \(f_{i,j}\) 表示前 \(i\) 种元素组成长度为 \(j\) 的序列有多少种可能,易得状态转移方程。
初始化 \(f_i=\langle 1,1,1,0,0,\cdots\rangle\) 表示只用第 \(i\) 种元素组成长度为 \(0,1,2\) 的序列的方案数均为 1。
发现这是指数生成函数的卷积形式。
每种元素组成序列的方案数的生成函数 \(F(x)=1+x^1+\frac{x^2}{2}\)。
最终的答案就是 \(n^n)\)。
狄利克雷生成函数
组合数学
\(C_{n}^{m}\) 在数学中也可以记作 \(n\choose m\) 表示 \(n\) 个元素中选 \(m\) 个元素不考虑元素顺序的方案数。
通常情况下只会用到 1 式。
当 \(m>n>0\),\(C_{-n}^{m}=\frac{\prod_{i=-n-m+1}^{-n}i}{m!}=\frac{(-1)^m(n+m-1)(n+m-2)\cdots n}{m!}=(-1)^m C_{n+m-1}^{n-1}\)
二项式定理
\((a+b)^n=\sum_{i=0}^{n} {n\choose i}a^ib^{n-i}\)
\((a+b)^{-n}=\sum_{i=0}^{\infty} {-n\choose i}a^ib^{n-i}=\sum_{i=0}^{\infty}(-1)^i{n+i-1\choose n-1}a^ib^{n-i}\)
常用公式
\(\sum_{i=0}^{n} {n\choose i}=2^n\)
\(\sum_{i=0}^{n} {n\choose i}(-1)^i=0\)
\(\sum_{i=0}^{n} {n\choose i}x^i=(1+x)^n\)
\(\sum_{i=0}^{k} {n\choose i}{m\choose k-i}={n+m\choose k}\)
\({n\choose i}={n-1\choose i-1}+{n-1\choose i}\)
\({n+1\choose m+1}=\sum_{i=m}^{n}{i\choose m}\)
\(\sum_{i=0}^{k} {n+1\choose i}=\sum_{i=0}^{k}{n\choose i}+{n\choose i-1}=2\sum_{i=0}^k {n\choose i}-{n\choose k}\)
\(\sum_{i=a}^{b} {n+i-1\choose n-1}={n+b \choose n}-{n+a-1\choose n}\)
\(\sum_{i=0}^n{n\choose i}\cdot i^2=n\cdot(n+1)\cdot 2^{n-2}\)
卡特兰数
\(C_n={2n\choose n}-{2n\choose n+1}\)
\(C_n=\frac{{2n\choose n}}{{n+1}}\)
出栈序列
\(n\) 个元素,进栈序列为 \(1,2,3,\cdots,n\) 求有多少种出栈序列。
考虑枚举最后一个出栈的数,设 \(f_x\) 表示 \(x\) 个数依次进栈有多少种出栈序列,\(f_1=1\),易得:
\(f_n=\sum_{i=1}^{n}f_{i-1}f_{n-i}\)
把一次进栈表示为 \(+1\),出栈表示为 \(-1\)。
那么所有操作就可以表示为一个由 \(n\) 个 \(+1\) 与 \(n\) 个 \(-1\) 组成的长为 \(2n\) 的序列。显然对于这个序列有一个限制:对于所有前缀和均需要大于 \(0\)。
考虑转换为所有序列个数-不合法序列个数。所有序列个数显然是 \(2n\choose n\)。考虑求出不合法序列数量。
将每个不合法序列第一个前缀和小于 \(0\) 的前缀反转(\(+1 \to -1\),\(-1 \to +1\)),因为是第一个小于 \(0\) 的前缀和,那么必定值为 \(-1\),即由 \(x\) 个 \(+1\) 与 \(x+1\) 个 \(-1\) 组成此前缀,反转后就是和为 \(1\),由 \(x+1\) 个 \(1\) 与 \(x\) 个 \(-1\) 组成的前缀,此时整个序列就成了 \(n+1\) 个 \(+1\),与 \(n-1\) 个 \(-1\),这种序列共有 \(2n\choose n+1\) 个,合法的序列个数即为 \({2n\choose n}-{2n\choose n+1}=C_n\)。
而一开始的递推式就是卡特兰数的递推式。
\(C_1=1\\ C_n=\sum_{i=1}^{n}C_{i-1}C_{n-i}\;,\;(n\ge 2)\)
证明每种由 \(n+1\) 个 \(+1\) 与 \(n-1\) 个 \(-1\) 组成的序列都对应一种不合法序列
对于两个不同的不合法序列 \(A,B\),假设 \(A\) 反转部分为 \([1,a]\),\(B\) 反转部分为 \([1,b](b\ge a)\),因为两序列不同,反转后相同只有以下情况:
\(A_{[1,a]}=B_{[1,a]},A_{[a+1,b]}=\neg B_{[a+1,b]}\)
而这显然不存在,因为 \(A_{[1,a]}\) 和小于 0,而根据定义,\(b\) 是第一个满足前缀和小于 0 的位置,则此时必须满足 \(a=b\),则此时 \(A=B\) 矛盾,则每种由 \(n+1\) 个 \(+1\) 与 \(n-1\) 个 \(-1\) 组成的序列仅对应一种不合法序列。
而每种由 \(n+1\) 个 \(+1\) 与 \(n-1\) 个 \(-1\) 组成的序列必定能找到任意前缀和等于 1 的位置,将该前缀反转后必定对应一不合法序列。所以这是一个双射。
二叉树形态
设 \(f_x\) 表示 \(x\) 个节点构成二叉树的形态,\(f_x\) 的转移就是枚举根节点左右子树的形态。
\(f_x=\sum_{i=1}^{n}f_{i-1}f_{n-i}\)
容易发现这就是卡特兰数的递推式,所以 \(n\) 个节点的二叉树的形态数同样是 \(C_n\)。
多重集排列数
给定 \(n\) 个球,有 \(m\) 种颜色,第 \(i\) 种颜色的球有 \(c_i\) 个,问有多少种长度为 \(n\) 的排列。
\(ans=\frac{(\sum c_i)!}{\prod c_i!}\)
可以理解为 \(n\) 个球任意排列再容斥掉相同颜色的球任意排列对答案的影响。
示例:
给定 \(k\) 个连通块,第 \(i\) 个连通块大小为 \(siz_i\),要求连接 \(k-1\) 条边使得整个图连通,求有多少种连边方案。
这个问题其实是与 Prüfer 序列 有关,不过放在这写一下吧。
Prüfer 序列把无根树对应一个序列,钦定 \(n\) 为树根,因为是无根树所以没有影响,构建过程为:
- 选择一个编号最小的叶子节点,将其父亲节点假如序列末端
- 删除编号最小的叶子节点
Prüfer 序列的性质
在构造完 Prüfer 序列后原树中会剩下两个结点,其中一个一定是编号最大的点 \(n\)。
每个结点在序列中出现的次数是其度数减 1。(没有出现的就是叶结点)
摘自 oiwiki
符合条件的 Prüfer 序列的个数对应了符合条件的无根树的形态数。
证明
证明形态不同的树所构建的 Prüfer 序列互不相同即可,即一个 Prüfer 序列只能对应一棵树(根据 Prüfer 序列建立的树形态唯一)。
考虑根据 Prüfer 序列建树,设 Prüfer 序列 为 \(P\),假设现在遍历到 \(i\) 那么在\(P_{[i,n-2]}\) 中没有出现的节点必然都是此时的叶子节点,那么将编号最小的未钦定父亲的叶子节点的父亲设为 \(P_i\),就得到了一棵唯一的树。
把连通块看作一个点,设第 \(i\) 个点度数为 \(d_i\),根据 Prüfer 序列的性质,第 \(i\) 个点会在 Prüfer 序列中出现 \(d_i-1\) 次,就是子节点数(因为保留了 2 个点所以对于树根 \(n\) 也只会在序列中出现 \(d_n-1\) 次),那么对于有可能的 Prüfer 序列个数就可以用多重集排列数求出 \(\frac{(n-2)!}{\prod (d_i-1)!}\)。
再考虑连通块大小的影响,对于每条从连通块 \(u\) 连向连通块 \(v\) 的边都有 \(siz_u\cdot siz_v\) 种选择,那么所有边的连边方案数为 \(\prod siz_u\cdot siz_v\)。发现对于连通块 \(i\),\(siz_i\) 被乘了 \(d_i\) 次,所以连边方案数等同于 \(\prod siz_i^{d_i}\)。
则此题的答案为 \(\frac{(n-2)!}{\prod (d_i-1)!}\cdot \prod siz_i^{d_i}\)。
CF294C Shaass and Lights
也可以用多重集排列数解决,这里直接搬之前写的题解了 link。
杂项
- \(\forall\gcd(a,b)=1,(0<a<b)\;,\gcd(b-a,b)=1\)。
证明
若 \(\gcd(b-a,b)=n(n\not=1)\),则 \(b-a=nq,b=np,(q<p)\),则 \(a=(p-q)n\)。
则 \(\gcd(a,b)=\gcd((p-q)n,np)\ge n\),显然不成立。
用这个结论可以推出 \(\sum_{i=1}^n i[\gcd(i,n)=1]=\frac{\varphi(n)}{2}n\)。
因为若对于一个 \(i\),\(\gcd(i,n)=1\)。那么 \(\gcd(i,n-i)=1\),那么每队 \(i\) 与 \(n-i\) 对答案的贡献为 \(n\),共有 \(\frac{\varphi(n)}{2}\) 对,则最终答案 \(\frac{\varphi(n)}{2}n\)。
- \(n\) 个数的排列 \(a\) 其相邻两数之差的绝对值的 \(\gcd\) 为 1。
证明
若相邻两数之差的绝对值的 \(\gcd\) 为 \(k\),则 \(\forall i\in[1,n]\;,a_i-a_1=pk,(p\in\mathbf{R})\),显然当且仅当 \(k=1\) 时才能满足。
同理可得公差为 \(k\) 的等差数列的任意排列相邻两数之差绝对值的 \(\gcd\) 为 \(k\)。

浙公网安备 33010602011771号