ZROI 暑期高端峰会 A班 Day4 生成函数

一般生成函数

很普及组,不讲了

生成函数是一种形式幂级数,也就是我们只关心系数,不关心未知数具体的值。

比如 \(\sum\limits_{i\ge 0}x^i=\frac{1}{1-x}\)。虽然只有 \(0<x<1\) 时才是成立的,但是我们不管。

???

4 种东西,红黄蓝绿,都有无限个。现要求选出 \(n\) 个,要求红的偶数个,黄的 \(5\) 的倍数个,蓝的最多四个,绿的最多一个。问方案数。

生成函数瞎推一下,答案的生成函数 \(\frac{1}{(1-x)^2}\)

组合意义理解一下,第 \(n\) 项系数是 \(\binom{n+2-1}{2-1}=n+1\)。答案就是 \(n+1\)

指数型生成函数

还是很普及组,不讲了

指数型生成函数就是 \(\sum\limits_{i\ge 0}a_i\frac{x^i}{i!}\)。如果把两个指数型生成函数卷起来,就乘出来了组合数。

循环卷积

好像不怎么记得了……回去补一补。

(好的补完了)

考虑 \(A(x)=\sum\limits_{i=0}^{n-1}x^ia_i,B(x)=\sum\limits_{i=0}^{n-1}x^ib_i\),如何求出它们的循环卷积 \(C(x)\)

还是考虑点值变换后:

\[C(\omega_{n}^k)=\sum\limits_{i=0}^{n-1}\omega_n^{ik}\sum\limits_{j=0}^{n-1}a_jb_{i-j\bmod n} \]

\[C(\omega_{n}^k)=\sum\limits_{i=0}^{n-1}\sum\limits_{j=0}^{n-1}\omega_n^{(i+j)k}a_ib_j \]

\[C(\omega_{n}^k)=(\sum\limits_{i=0}^{n-1}\omega_n^{ik}a_i)(\sum\limits_{j=0}^{n-1}\omega_n^{jk}b_j) \]

\[C(\omega_{n}^k)=A(\omega_{n}^{k})B(\omega_{n}^k) \]

一般直接暴力求值插值可以 \(O(n^2)\)。比起纯暴力卷积的优点在不用频繁变换,比如快速幂就可以做到 \(O(n^2+n\log k)\) 而不是 \(O(n^2\log k)\)

对于一些比较特殊的 \(n\) 和模数可以质因子分解,类似普通 FFT 每次除以 2 分治,这里对任意一个质因子分解即可。([CTSC2010]性能优化

还有二维循环卷积……回去补一补。

还有,还有……

???

\(n\)\(m\) 边的有向图,每条边边权是二元组 \((a_i,b_i)\)。你身上有一个二元组 \((a,b)\),初始是 \((0,0)\)。每过一条边,二元组会变成 \(((a+a_i)\bmod n,(b+b_i)\bmod(n-1))\),另外给定一个 \(k\),对于每个点 \(i\) 和二元组 \((x,y)\),问从 \(i\) 开始走恰好 \(k\) 条边回到 \(i\),且二元组变成 \((x,y)\) 的方案数。答案对 \(1163962801\) 取模。

\(n\le 22,m\le 10000,k\le 10^9\)

\(n\times (n-1)\) 的矩阵作为转移矩阵的元素,乘法定义为二维循环卷积。时间复杂度 \(O(n^7\log k)\)

既然是二维循环卷积,可以把每个矩阵 DFT,卷积后再 IDFT,复杂度就是 \(O(n^6+n^5\log k)\)

模数不太友好,但是也有特殊之处,也可以瞎搞。

(考虑 \(998244353\) 能作为 NTT 模数的原因:\(998244353=2^{23}\times 19+1\),而原根——模意义下的单位根——我们要用到的次方是 \(g^{\frac{p-1}{d}}(d|n)\)(因为我们每次分治是分成两份,所以我们要把 \(n\) 变成 \(2\) 的次幂),所以如果 \(p-1\)\(2\) 的个数不多就挂了。那么每次分治我们可以不是分成两份。对于这个模数,发现……#$&!(*#(*&@,所以就可以了。)

某个 TC Hard

\(n\) 次多项式 \(P(x)\),满足 \([x^i]P(x)=[x^{n-i}]P(x)\),也就是对称的。现在你知道 \(P^2(x)\)\(\bmod x^{n+1}\) 意义下循环卷积的值,求 \(P(x)\)

\(n\le 40\)

考虑 \(P(\omega_n^k)=\sum\limits_{i=0}^{n-1}\omega_n^{ik}P_i\)\(P(\omega_n^{n-k})=\sum\limits_{i=0}^{n-1}\omega_n^{i(n-k)}P_i=\sum\limits_{i=0}^{n-1}\omega_n^{ik}P_{n-i}\),实际上就是一个东西。

现在你知道每个 \(P^2(\omega_{n}^{k})\),也就能求出 \(P(\omega_n^k)\),注意要保持 \(P(\omega_n^k)=P(\omega_n^{n-k})\)。也就能插值回去。(好像是吧?)

???

\(m\) 个点的图,图中任意一条从 \(s\)\(t\) 长度为 \(k\) 的倍数的路径会对答案产生 \(\binom{n}{len}\) 的贡献。答案对 \(P\) 取模。

路径不一定是简单路径。

\(m\le 10,k\le 1000,P\equiv 1\pmod k,n\le 10^{18}\)

首先发现这个贡献式很鬼畜,考虑换掉。

对每个点都连个自环。那么本来长度为 \(len\) 的路径,现在就变成了一定要走 \(n\) 个时刻,其中选 \(len\) 个时刻干正事,剩下的碌碌无为。

直接矩阵快速幂 \(O(k^2m^3\log n)\),不行。

发现 \(P\equiv 1\pmod k\),所以可以用一个 \(k\) 次单位根来 DFT,模数也很好。

复杂度 \(O(km^3\log n+k^2)\)

Polya 定理

首先有 Burnside 引理:

然后有 Polya 定理:

(啥玩意来着?先去补一补)

生成函数可以和 Polya 定理合在一起。具体?咕了。

泰勒展开

\(F(x)\)\(x_0\) 处展开,有:

\[F(x)=\sum\limits_{i\ge 0}\frac{(x-x_0)^iF^{(i)}(x_0)}{i!}$$,其中 $F^{(i)}$ 表示将 $F$ 求导 $i$ 次。 ## 牛顿迭代 给定函数 $G(x)$,求多项式 $G(F(x))\equiv 0\pmod {x^n}$。 考虑倍增,假如我们已经求出了 $G(F_0(x))\equiv 0\pmod{x^{\lceil\frac{n}{2}\rceil}}$。 做泰勒展开有: $$G(F(x))=G(F_0(x))+\sum\limits_{i\ge 1}\frac{(F(x)-F_0(x))^iG^{(i)}(F_0(x))}{i!}\]

不难发现

\[(F(x)-F_0(x))^2\equiv 0\pmod{x^{2\lceil\frac{n}{2}\rceil}} \]

所以

\[0\equiv G(F(x))\equiv G(F_0(x))+(F(x)-F_0(x))G'(F_0(x))\pmod{x^n} \]

\[F(x)\equiv F_0(x)-\frac{G(F_0(x))}{G'(F_0(x))}\pmod {x^n} \]

多项式求逆

可以用牛迭推。

然而倍增也可以。

而且写多了都能记住了。

多项式除法

反转系数就行了。

也写过很多次,也记住了。

多项式 ln

导一下积一下就好了。

跟数没有区别。

注意的是常数项为 \(0\) 时才有意义。

多项式 exp

用牛迭推一下就好了。

注意的是常数项为 \(1\) 时才有意义。

其实写多了也能记住了。

多项式多点求值

给定 \(n\) 次多项式 \(P\)\(m\) 个点 \(x_i\) 求所有 \(P(x_i)\)

考虑分治,分成左右两半,对于左右分别求两个多项式 \(A_l(x)=\prod\limits_{i\in left}(x-x_i),A_r(x)=\prod\limits_{i\in right}(x-x_i)\)

以左边的点为例,对于左边的点都有 \(A_l(x_i)=0\)。设 \(F(x)\bmod A_l(x)=R_l(x)\),那么有 \(F(x)=R_l(x)\)。直接分治即可。

如何求每个 \(A(x)\)?可以做另一次分治。总复杂度 \(O(n\log^2 n)\)(假设 \(n,m\) 同阶)。

多项式快速插值

就是给 \(n+1\) 个点和点值,要插值。

考虑拉格朗日插值。

分治,令 \(m=\lfloor\frac{n}{2}\rfloor,y_i=\frac{F(x_i)}{\prod\limits_{j\ne i}(x_i-x_j)}\)

那么 \(F(x)=\sum\limits_{i=0}^ny_i\prod\limits_{j\ne i}(x-x_j)\)

\[F(x)=\sum\limits_{i=0}^my_i\prod\limits_{j=0,j\ne i}^m(x-x_j)\prod\limits_{j=m+1}^n(x-x_j)+\sum\limits_{i=m+1}^ny_i\prod\limits_{j=0}^m(x-x_j)\prod\limits_{j=m+1,j\ne i}^n(x-x_j) \]

\[F(x)=\prod\limits_{j=m+1}^n(x-x_j)\sum\limits_{i=0}^my_i\prod\limits_{j=0,j\ne i}^m(x-x_j)+\prod\limits_{j=0}^m(x-x_j)\sum\limits_{i=m+1}^ny_i\prod\limits_{j=m+1,j\ne i}^n(x-x_j) \]

这里可以分治。

首先前面每个多项式先来一次分治求,\(O(n\log^2n)\)

当分治到只有一个点的时候,就要用上 \(y_i\) 了。如何求 \(y_i\)

\(F(x_i)\) 已知,所以让 \(z_i=\prod\limits_{j\ne i}(x_i-x_j)\)

\(G(x)=\prod\limits_{i=0}^n(x-x_i)\),所以 \(z_i=\frac{G(x)}{x-x_i}\)

根据洛必达法则,上下求个导,\(z_i=G'(x_i)\)

所以 \(y_i=\frac{F(x_i)}{G'(x_i)}\)

\(G(x)\) 在前面的分治中已经求过,求导后弄个多点求值,可以全部求出。

总复杂度 \(O(n\log^2n)\)

分拆数

之前讲过了。

\(F(x)\) 为答案的生成函数。

\[F(x)=(1+x+x^2+\dots)(1+x^2+x^4+\dots)\dots \]

\(F(x)=\prod\limits_{i\ge 1}\frac{1}{1-x^i}\)

\[\ln F(x)=-\sum\limits_{i\ge 1}\ln(1-x^i) \]

\[\ln F(x)=\sum\limits_{i\ge 1}\sum\limits_{j\ge 1}\frac{x^{ij}}{j} \]

\[\ln F(x)=\sum\limits_{i\ge 1}x^i\sum\limits_{j|i}\frac{1}{j} \]

\(O(n\log n)\) 预处理,\(O(n\log n)\) exp 回去。复杂度 \(O(n\log n)\)

还有五边形数的做法。

不知道为什么,但是就是可得 \(f_i=f_{i-p_1}+f_{i-p_{-1}}-f_{i-p_2}-f_{i-p_{-2}}+f_{i-p_3}+f_{i-p_{-3}}-\dots\)

其中 \(p_i\) 是第 \(i\) 个五边形数,满足 \(p_i=\frac{3i^2-i}{2}\)

直接做是 \(O(n\sqrt{n})\)。写成生成函数的形式,发现可以多项式求逆,\(O(n\log n)\),常数小很多。

cxk

\(n\) 个数 \(a_i\)。要选取一组 \(x_i\) 使得 \(\sum x_i=1\),要求存在一个 \(b\) 使得对于任意正整数 \(k\)\(\sum x_ia_i^k=b^k\)

\(x_i\) 不一定要在 \([0,1]\)

问每个 \(x_i\)。对 \(998244353\) 取模。

\(n\le 10^5\)

转化为一个方程组。发现只需要 \(n\) 条就够了(\(\sum x_i=1\) 可以看成是 \(k=0\) 时)。

发现这就是个范德蒙德矩阵。行列式可以快速计算:\(\prod\limits_{i<j}(x_j-x_i)\)

使用线性代数里的 Cramer 法则,\(x_i=\frac{\det(A_i)}{\det(A)}\)

发现分子是个很熟悉的形式。对,就是 \(\prod\limits_{j\ne i}(x-x_j)\)。用上面快速插值的方法即可。

中间掉线,错过了一题

???

已知 \(f(x)=\prod\limits_{i=1}^n(1+a_ix),g(x)=\prod\limits_{i=1}^n(1+b_ix)\),已知 \(f(x),g(x)\),求 \(h(x)=\prod\limits_{i=1}^n\prod\limits_{j=1}^n(1+a_ib_jx)\) 的第 \(k\) 项。

\[\ln f(x)=\sum\limits_{i=1}^n\ln(1+a_ix) \]

好像瞎推一波就行了?看起来没什么技术含量。

淘汰赛

\(n\) 个人的序列,进行 \(m\) 次比赛,每次比赛把幸存者分成若干段,每段中选手编号连续且至少两个,比赛完之后每段中恰好一个人获胜。每轮比赛过后,对选手重新编号(离散化)。\(m\) 次比赛后恰好剩下一个人。问有多少种不同的比赛过程。

\(n\le 10^{18},m\le 15\)

\(m=1\) 时生成函数是 \(F_1(x)=\frac{x^2}{1-x}\)

\(m>1\)\(F_m(x)=\frac{F_{m-1}(x)^2}{1-F_{m-1}(x)}\)

\(F_m(x)=\frac{f_m(x)}{g_m(x)}=\frac{F_{m-1}(x)^2}{1-F_{m-1}(x)}\),大力推一波有 \(f_{m}(x)=f_{m-1}(x)^2=x^{2^m},g_m(x)=g_{m-1}(x)(g_{m-1}(x)-f_{m-1}(x))\)

要求就是 \([x^n]\frac{x^{2^m}}{g_m(x)}\pmod {x^{n+1}}\)

至于底下这东西的逆怎么求?要求的次数很高,不能简单求。但是发现可以通过前 \(n-1\) 项推出第 \(n\) 项。用的是一个 \(2^m\) 阶的递推公式。

\(O(2^mm\log n)\)

posted @ 2019-08-20 13:24  ATS_nantf  阅读(216)  评论(0编辑  收藏  举报