多项式全家桶

更多代码请移步一些模板

多项式乘法

问题

已知多项式 \(F(x)\)\(G(x)\),求 \(H(x)=F(x)\cdot G(x)\)。多项式系数为实数/整数(求模意义下多项式乘积)。

FFT/NTT

详见别人的博客。由于有些复杂,而且网上资料很多,作者懒得写了。而且写了也对作者没什么意义。

任意模数NTT

有些毒瘤出题人,不想用 998244353 当模数,怎么办呢?

如果考场上遇到多项式题并且能想出来,却不会三模NTT就会产生一种吃了屎的感觉...

如果要求对模 \(p\) 意义下的最终多项式,那么模 \(p\) 意义下最初多项式数值大小不超过 \(p\),于是最终多项式每个位置的数值不超过 \(np^2\)\(p\) 如果不超过 \(10^9+7\) ,那么 \(np^2\le 10^6\cdot (10^9+7)^3 \approx 10^{23}\)。所以只要找到三个模数,使得他们可以做NTT并且乘积 \(>10^{23}\) 就可以了。最后将三个模数合并即可。

多项式求逆

引言

为什么多项式还可以求逆?

举个例子:

\[\frac{1}{1-x}=1+x+x^2+\cdots \]

所以,\(\Large\frac{1}{1-x}\) 可以写成无限项多项式的形式。但一般问题只需要求其前若干项。

其实,更加可以理解的定义是这样的:

\[\frac{f(x)}{g(x)}=h(x)\Leftrightarrow f(x)=g(x)\cdot h(x) \]

那么我们可以验证上面那个东西,

\[(1-x)(1+x+x^2+\cdots )=(1+x+x^2+\cdots)-(x+x^2+\cdots)=1 \]

另外,这并不能直接把 \(x\) 带入。比如 \(x=100\) 的时候明显这不正确。

其实,\(\Large \frac{1}{1-x}\) 是一个生成函数吧。代表着数列 \(1,1,1,1,\cdots\)

问题

对多项式\(f(x)\) 求多项式 \(g(x)\) 使得 \(f(x)\cdot g(x)\equiv 1\pmod {x^n}\)

这里的\(\pmod {x^n}\) 的意义其实就是“\(x\) 的次数最低的 \(n\) 项”

做法

考虑使用倍增。设 \(h(x)\cdot f(x)\equiv1\pmod {x^{\lceil\frac{x}{2}\rceil}}\)。那么:

\[\because f(x)\cdot g(x)\equiv 1\pmod {x^{\lceil\frac{x}{2}\rceil}}\\ \therefore f(x)(h(x)-g(x))\equiv 0\pmod {x^{\lceil\frac{x}{2}\rceil}} \]

观察 \(f(x)(h(x)-g(x))\) 的常数项,由于 \(f(x)\) 的常数项不为 0,所以 \(h(x)-g(x)\) 的常数项必然为 0(根据 \(f(x)(h(x)-g(x))\)的后 \(n\) 项均为 0 可知). 再观察 \(f(x)(h(x)-g(x))\) 的一次项,一次项是 \(f(x)\) 的常数项 * \(h(x)-g(x)\) 的一次项 + \(h(x)-g(x)\) 的常数项 * \(f(x)\) 的一次项。所以必然 \(h(x)-g(x)\) 的一次项也为 0.以此类推,\(h(x)-g(x)\equiv 0\pmod {x^{\lceil \frac{n}{2}\rceil}}\)

发现 \(h(x)-g(x)\) 的后 \(\lceil \frac{n}{2}\rceil\) 项都相等。

考虑到这是在 \(\pmod x^{\lceil \frac{n}{2}\rceil}\) 意义下的,那么平方就可以转化到 \(\pmod {x^n}\) 意义下的。于是有 \((h(x)-g(x))^2\equiv 0\pmod {x^{ n}}\)。展开可以得到 \(h(x)^2-2h(x)g(x)+g(x)^2\equiv 0\pmod {x^n}\)

\(h(x)-g(x)\) 变换为 \(\pmod {x^n}\) 意义下的式子。

发现这是一个关于 \(g(x)\) 的二次式,但是却不能使用求根公式求它,那样还得套上一个多项式开根。。所以考虑利用 \(f(x)\cdot g(x)\equiv 1\pmod {x^n}\) ,将等式两边同时乘以 \(f(x)\),这样可以将 \(g(x)\) 降次得到 \(g(x)\) 的最终表达式 \(g(x)=2h(x)-f(x)h(x)^2\)

将关于 \(g(x)\) 二次式通过已知条件化为关于 \(g(x)\) 的一次式。

多项式除法

问题

对于两个多项式 \(F(x)\)\(G(x)\) (其中 \(F(x)\)\(n\) 次多项式, \(G(x)\)\(m\) 次多项式,\(n>m\))。求多项式 \(Q(x)\)\(R(x)\) ,满足 \(F(x)=Q(x)\cdot G(x)+R(x)\) ,并且 \(Q(x)\)\(n-m\) 次多项式, \(R(x)\) 是小于 \(m\) 次的多项式。

做法

咕咕咕。

多项式\(\ln\)

为什么多项式可以求 \(\ln\)

因为多项式求 \(\ln\) 后再泰勒展开还是多项式。

问题

已知 \(G(x)\),求 \(F(x)\equiv \ln G(x) \pmod {x^n}\)

做法

对两边进行求导,有以下式子:

\[\begin{aligned} F(x)&=\ln G(x)\\ \Rightarrow F'(x)&=(\ln G(x))'\\ \Rightarrow F'(x)&=\frac{G'(x)}{G(x)}\\ \Rightarrow F(x)&=\int \frac{G'(x)}{G(x)}\cdot \text{dx} \end{aligned} \]

这里求导的意义主要在于发现 $\ln $ 的导数非常好计算,并且求导的逆运算积分可以 \(\mathcal O(n)\) 求出。

但是会发现这样 \(F(x)\) 的常数项可能求不出来。而模意义下 \(\ln\) 无法定义,但也不伤大雅。考虑 \(F(0)=\ln G(0)\)。所以 \(F(x)\) 的常数项 \(=\ln G\)的常数项 。

泰勒展开

震惊!BJ某傻瓜看泰勒展开2h为看懂!原因竟是...

他看错了一句话。

读不懂多读几遍是非常正确的选择...看知乎文章,觉得人家写错了;数小时之后,恍然大悟。可能文章的不足时没有举例子,我的不足是没有多读几遍吧。

问题

对于一些式子,比如 \(\sin x,\exp(x),\ln x\) 之类,不太好使用计算多项式的办法计算,亦无法写成形式幂级数的形式。那么这就需要用多项式逼近函数。在高度逼近的情况下,这些函数竟然完全相等了!别问我问什么

做法

如果从 \(x_0\) 点开始拟合函数 \(f(x)\) ,拟合成的函数为 \(g(x)\)

那么泰勒展开的拟合策略是这样的:让 \(f(x)\)\(g(x)\) \(x_0\)的任意阶导数都相等。注意!是在 \(x_0\) 处!

然后就神奇的拟合成了多项式:

\[g(x)=f(x_0)+\sum_{i=1}^n (\frac{f^{(i)}(x-x_0)^i}{i!} \]

其中,\(x_0\) 为一个固定数。

常见公式

主要还是靠现场推吧,背这个东西意义不大。

从网上摘了一个,不保证正确性(没仔细看。。)。

多项式牛顿迭代

这是一个非常实用的东西。可以解决许多多项式问题,诸如多项式求逆、多项式\(\ln\) 还有多项式 \(\exp\)

问题

已知函数 \(f(x)\) ,求多项式 \(g(x)\) 使得 \(f(g(x))\equiv 0\pmod {x^n}\)

做法

Newton's Method

考虑倍增(非常类似多项式求逆)。

若已知 \(f(g_0(x))\equiv 0\pmod {x^{\large\lceil \frac{n}{2}\rceil}}\) ,考虑用多项式 \(g_0(x)\) 推出 \(g(x)\)

\(f(x)\)\(x_0=g_0(x)\) 处泰勒展开,可知:

\[f(g_0(x))+\sum_{i=1}^{\infin}f^{(i)}(g_0(x))\cdot \frac{(g(x)-g_0(x))^i}{i!}\equiv 0\pmod {x^n} \]

这里泰勒展开的意义在于将一个不知道任何性质的函数 \(f(x)\)\(f(x)\) 可以是 \(\ln\)\(\exp\) 等函数) 化为多项式。

在后面的求和式中,当 \(i\ge 2\) 有:

\[(g(x)-g_0(x))^i\equiv 0\pmod {\large x^{n}} \]

所以:

\[f(g_0(x))+f'(g_0(x))\cdot \frac{g(x)-g_0(x)}{1!}\equiv 0\pmod {x^n} \]

那么有:

\[g(x)\equiv g_0(x)-\frac{f(g_0(x))}{f'(g_0(x))}\pmod {x^n} \]

多项式\(\exp\)

为什么多项式可以 \(\exp\)

因为多项式 \(\exp\) 后泰勒展开还是多项式。。

是的,每回这个问题的答案都是泰勒展开后都是多项式。

问题

求多项式 \(f(x)\) 使得 \(f(x)\equiv e^{g(x)}\pmod {x^n}\)

做法

考虑使用牛顿迭代。

首先考虑将式子转化为 \(\ln f(x)\equiv g(x) \pmod {x^n}\) 。然后再构造以下函数:\(h(f(x))=\ln f(x)-g(x)\) ,我们要求的函数就是满足 \(h(f(x))\equiv 0\pmod {x^n}\) 。注意,这里 \(h'(f(x))=\frac{1}{f(x)}\) ,这里 \(h\) 函数的参数实际上是个多项式。

所以使用牛顿迭代的结论可知:

\[\begin{aligned} f(x)&\equiv f_0(x)-\frac{h(f_0(x))}{h'(f_0(x))}\pmod {x^n}\\ \Rightarrow f(x)&\equiv f_0(x)-\frac{\ln f_0(x)-g(x)}{\frac{1}{f_0(x)}}\pmod {x^n}\\ \Rightarrow f(x)&\equiv f_0(x)(1-\ln f_0(x)+g(x))\pmod {x^n} \end{aligned} \]

所以,写个多项式求逆、多项式求导、多项式 $\ln $ 就可以解决了。

多项式快速幂

问题

已知函数 \(f(x)\) ,求 \(f(x)^a\)

做法

我们知道,\(f(x)^{a}=e^{a\ln f(x)}\)。所以完了。

注意分类讨论,可能 \(f(x)\) 的常数项不是 \(1\)

分治FFT

咕咕咕

posted @ 2020-06-21 18:57  acniu  阅读(121)  评论(0编辑  收藏  举报