省选复习

多项式全家桶

听起来很吓人的名字(在我学之前),慢慢知识积累上去,你会发现它就是一堆数学推导。

不断更新中...

当前进度:多项式exp / 常系数齐次线性递推

基础知识

微积分

(暂时)并不需要太高的水平,最基本的会即可。

基础求导:

(C'=0)

((x^n)'=nx^{n-1})

((e^x)'=e^x)

(ln'(x)=dfrac{1}{x})

((Cf(x))'=Cf'(x))

((fpm g)'=f'pm g')

((fg)'=f'g+fg')

((dfrac{f}{g})'=dfrac{f'g-fg'}{g^2})

(f(g(x))'=f'(g(x))g'(x))

基础积分:

把上面这些反过来

FFT/NTT

这还要讲?

泰勒展开

现在已知一个函数 (f(x))。要用一个多项式函数 (g(x)) 逼近它

考虑先选取一个起点 (x_0),以这个位置为参考 (一般这个位置要好算一些,或者有可以利用的数值)

然后我们的主体思路是,让 (f,g)(x_0) 处的值,一阶导,二阶导,三阶导...都相同。

首先我们让 (f,g)(x_0) 处相同。那 (g) 先加上一项 (f(x_0)) 的常数。

然后我们让它的一阶导相同,那我们要给它来点多项式了。但是注意我们不能改变取值,于是我们只能加上 (x-x_0) 的若干倍。

(g_k) 表示一个函数,它在 (x_0) 处的 (k) 阶导和 (f) 相同。

考虑 (g_1)

(x=x_0) 时,(g_1'(x)=f'(x_0))

同时积分,(g_1(x)=xf'(x_0)+C)

为了凑 (x-x_0),我们令 (g_1(x)=(x-x_0) f'(x_0))

考虑 (g_2)

同时积分两次

(g_2(x_0)=dfrac{1}{2} f''(x_0)x_0^2 + C(x))(C(x)) 是任意至多一次的多项式。

同理,我们令 (g_2(x)=dfrac{1}{2}f''(x_0) (x-x_0)^2)

这里出现了分数,容易发现这个分数是积分的时候积出来的,积了多少次,就会有多少个,所以是一个阶乘

所以 (g_k(x)=dfrac{f^{(k)}(x_0) (x-x_0)^k}{k!})

然后把所有的 (g_k) 和常数项加起来,得到:

[g(x)=sumlimits_{i=0}^{infin} dfrac{f^{(i)}(x_0)(x-x_0)^i}{i!} ]

牛顿迭代

首先,我们对一个多项式 (mod {x^n}),意思就是取前 (n-1) 项,这个东西想想就明白了。

另外,因为同余 (equiv) 很不好打,后面 (=) 也表示同余 —— 这个写法很不好,但看到后面有 (pmod{...}) 便可知这个 (=) 表示同余。

回到正题。现在我们要解一个多项式方程 (E(f)=0),其中 (f) 是一个未知多项式,我们要找出来它。

而实际问题中我们一般只需要 (f) 的前 (k) 项,也就是 (mod x^k) 的解。

假设我们知道了 (E(f_0)=0 pmod{x^n}),要找一个 (E(f)=0 pmod{x^{2n}})

假设能这么求,那么求 (log) 次,就可以求出 (mod x^k) 的解了。

我们在 (f_0) 处展开 (E),并求 (f) 位置的值 (没错,展开结果是一个多项式套多项式,会有若干个 (f) 的若干次方)

(E(f)=E(f_0)+E'(f_0)(f-f_0)+dfrac{E''(f_0)(f-f_0)^2}{2!}+...)

我们强制令 (f=f_0 pmod{x^n}),容易证明,如果 (E) 有解,那这样一定能找到一个解。

证:

假设 (E(g)=0 pmod{x^{m}}),其中 (m) 是一个足够大的数 —— 比我们要用的所有 (n)

考虑 (f=gmod x^n)

(g) 处展开 (E),代入 (f) 求值

(E(f)=E(g)+E'(g)(f-g)+...)

由于 (f=g pmod{x^n}),所以 (f-g=0 pmod{x^n}) ,于是 (E(f)=E(g)=0 pmod{x^n})

也就是我们要找的 (mod x^n) 的解,当然,(m) 再大一点,容易证明,把 (n) 换成 (2n) ,或者是我们想要的 (k) ,都是成立的,都能找到解

然后注意到 ((f-f_0)^2=0pmod{x^{2n}}),后面的次数更大,都包含这个因子 —— 所以从 (2) 开始我们全都不用要了。

然后 (E(f)=E(f_0)+E'(f_0)(f-f_0))

移项并整理:

[f=f_0-dfrac{E(f_0)}{E'(f_0)} ]

然后每次这么求一遍就可以了。关于如何算除法,后面再说。

牛顿迭代的代码实现

假设我们现在已经知道了多项式乘法,这里直接假设封装了 operator (实际上我并没有这么干,因为我试过一次,很慢,也不知如何优化)

相当于半个伪代码和C++

void solve(euqation E,poly& g,int n) 
// E 是那个方程
// 实际代码实现中, 通常是传一个方程的参数进来, 然后通过推式子手动求方程的值和求导之类的
// 另外, 一般这里的g是传数组进来, 就不用&了
{
	int len,lim;
	poly g=trival(); // 先瞪出来一个trival的边界值
	for(len=1;len<=(n<<1);len<<=1)
	{
		lim=len<<1; // 这个是 FFT/NTT 要用的

		E_=deri(E); // 求导
		// 实际上我们是需要手动求导的, 而且不会写成这样, 这里仅供示意
		g=g-E(g)*inv(E_(g)); // inv: 求逆, 后面讲, 乘以一个多项式的逆相当于除
        // 顺便, 一般这里求 E 啥的还要再来一堆辅助数组
	}
	return g;
}

别问我为啥要贴这个,我初学的时候尝试自己想怎么写,但是一直不知道lim和len咋搞

如果您自己想出来了,恭喜你,把我吊打了

多项式正题

多项式乘法

FFT/NTT 直接上

多项式求逆

已知 (f),求 (g) 使 (fg=1 pmod{x^k})

(g=f^{-1})。由于逆元的对称性,(f=g^{-1})

牛顿迭代需要用除法,而多项式求逆就是用来解决除法的,所以牛顿迭代比多项式求逆高 —— 换句话说我们没法用牛顿迭代算多项式求逆。这就好比你没法生下来你妈,因为你是你妈生的 超 级 加 辈

但是这个思路值得借鉴。假设有(g_0) 使 (fg_0=1 pmod{x^n}),求 (g) 使 (fg=1 pmod{x^{2n}})。还是令前 (n) 项相同,然后考虑 ((g-g_0)^2),显然它 (=0 pmod{x^{2n}})

展开它,变成

(g^2-2gg_0+g_0^2=0pmod{x^{2n}})

同时乘以 (f)

(fg^2-2fgg_0+fg_0^2=0pmod{x^{2n}})

我们设 (fg=1 pmod{x^{2n}}),所以可以代入一下变成

(g-2g_0+fg_0^2=0pmod{x^{2n}})

移项得:

[g=2g_0-fg_0^2 ]

然后迭代即可。上面提到,除相当于乘以逆元。于是就可以算除法了。

多项式对数函数(ln)

要求 (g(x)=ln(f(x)) pmod{x^k})

(x) 为主元来导,(g'(x)=dfrac{1}{f(x)}f'(x))

然后积回去:

[g(x)=int dfrac{f'(x)}{f(x)} ]

(为啥打中间是因为这样的积分好看,打在行间就是 (int)

多项式指数函数(exp)

非常好听的名字:exp。它也有很完美的性质,一切都是 (e) 这个神秘数字的魅力。

先回到正题。要求:(g=exp(f)=e^f pmod{x^n})

相当于 (ln(g)-f=0)

(E(g)=ln(g)-f)。易得 (E'(g)=dfrac{1}{g})(这里设 (g) 为主元,然后 (f) 就是常数,也不用链式法则了)

换句话说求的是 (dfrac{dE(g)}{dg})

(g=g_0-dfrac{E(g_0)}{E'(g_0)}=g_0-dfrac{ln(g_0)-f}{dfrac{1}{g_0}})

整理一下就是

[g=g_0(1-ln(g_0)+f) ]

然后它的完美性质是甚么?

假设我们知道一个东西 (A) ,它的数量的的生成函数是 (F)

然后有另一个东西 (B),它的数量的生成函数是 (G)

然后 (B) 是由若干个 (A) 无序拼起来的。

这样的例子很多,比如说置换是由循环置换拼起来的,任意图是由若干连通图拼起来的,森林是由树拼起来的...

然后 (G=exp(F))

为什么呢?枚举 (A) 用了多少个,假设是 (i) 个。然后它们的大小的和要等于 (n),也就是一个多元卷积的形式。又因为是无序的,所以要除以 (i!)

于是有 (G=sumlimits_{i=1}^{infin}dfrac{F^i}{i!})

然后这玩意就是 (exp(x))(x_0=0) 处的展开 (容易验证)。于是 (G=exp(F))

当然它还有更多完美的性质,此处略

不太有用的东西

指多项式开根/三角函数

题目里没见到过,只有板子里有。 也可能是我too young too simple

反正牛迭随便推一下就行了

多项式快速幂

先开 (ln),然后乘以 (k) (我们要的幂),然后再 (e) 回来。一个 (log),比倍增快速幂快。

多项式带余除法

给定 (F,G),次数分别是 (n,m)

(Q,R) 使得 (F=QG+R),其中 (R) 的次数必须小于 (m) —— 容易证明存在唯一的 (G,R)

(其中我们称 (Q) 为商,(R) 为余数)

考虑模 (x^n) 这个操作,它可以去掉多项式从 (n) 开始的更高的次数,只保留 ([0,n-1]) 次。换句话说,它体现在数组上去掉了一个 后缀

然后现在比较不好处理的就是这个 (R) 。我们希望用一个类似取模的东西,去掉一个 前缀,直接多项式乘法逆就可以求出 (Q) 了。

那这不是很好办么,前缀反过来就是后缀了。但是请注意,(R) 的次数很小,反过来的时候注意补项。

于是得到了问题的解决办法:

  • (F,G) 做一遍 (reverse),设得到了 (F_r,G_r)。然后 (Q=F_r imes (G_r)^{-1})
  • (R=F-QG),直接乘然后减就完了

常系数齐次线性递推

单独出来写吧,有点长

ko↑ko↓

多项式多点求值 / 快速插值

咕咕咕~

多项式复合 / 多项式复合逆

咕咕咕~

普通多项式和下降幂多项式的转化

斯特林数瞎搞一番就行了

本质上也是咕咕咕

鸽 王 争 霸 赛

原文地址:https://www.cnblogs.com/LightningUZ/p/14322096.html