更多代码请移步一些模板。
多项式乘法
问题
已知多项式 (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^2le 10^6cdot (10^9+7)^3 approx 10^{23})。所以只要找到三个模数,使得他们可以做NTT并且乘积 (>10^{23}) 就可以了。最后将三个模数合并即可。
多项式求逆
引言
为什么多项式还可以求逆?
举个例子:
[frac{1}{1-x}=1+x+x^2+cdots ]所以,(Largefrac{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 1pmod {x^n})
这里的(pmod {x^n}) 的意义其实就是“(x) 的次数最低的 (n) 项”
做法
考虑使用倍增。设 (h(x)cdot f(x)equiv1pmod {x^{lceilfrac{x}{2} ceil}})。那么:
观察 (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 0pmod {x^{lceil frac{n}{2} ceil}}) 。
发现 (h(x)-g(x)) 的后 (lceil frac{n}{2} ceil) 项都相等。
考虑到这是在 (pmod x^{lceil frac{n}{2} ceil}) 意义下的,那么平方就可以转化到 (pmod {x^n}) 意义下的。于是有 ((h(x)-g(x))^2equiv 0pmod {x^{ n}})。展开可以得到 (h(x)^2-2h(x)g(x)+g(x)^2equiv 0pmod {x^n}) 。
将 (h(x)-g(x)) 变换为 (pmod {x^n}) 意义下的式子。
发现这是一个关于 (g(x)) 的二次式,但是却不能使用求根公式求它,那样还得套上一个多项式开根。。所以考虑利用 (f(x)cdot g(x)equiv 1pmod {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}) 。
做法
对两边进行求导,有以下式子:
这里求导的意义主要在于发现 $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) 处!
然后就神奇的拟合成了多项式:
其中,(x_0) 为一个固定数。
常见公式
主要还是靠现场推吧,背这个东西意义不大。
从网上摘了一个,不保证正确性(没仔细看。。)。
多项式牛顿迭代
这是一个非常实用的东西。可以解决许多多项式问题,诸如多项式求逆、多项式(ln) 还有多项式 (exp)。
问题
已知函数 (f(x)) ,求多项式 (g(x)) 使得 (f(g(x))equiv 0pmod {x^n})
做法
Newton's Method
考虑倍增(非常类似多项式求逆)。
若已知 (f(g_0(x))equiv 0pmod {x^{largelceil frac{n}{2} ceil}}) ,考虑用多项式 (g_0(x)) 推出 (g(x)) 。
将 (f(x)) 在 (x_0=g_0(x)) 处泰勒展开,可知:
这里泰勒展开的意义在于将一个不知道任何性质的函数 (f(x))((f(x)) 可以是 (ln),(exp) 等函数) 化为多项式。
在后面的求和式中,当 (ige 2) 有:
所以:
那么有:
多项式(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 0pmod {x^n}) 。注意,这里 (h'(f(x))=frac{1}{f(x)}) ,这里 (h) 函数的参数实际上是个多项式。
所以使用牛顿迭代的结论可知:
所以,写个多项式求逆、多项式求导、多项式 $ln $ 就可以解决了。
多项式快速幂
问题
已知函数 (f(x)) ,求 (f(x)^a) 。
做法
我们知道,(f(x)^{a}=e^{aln f(x)})。所以完了。
注意分类讨论,可能 (f(x)) 的常数项不是 (1) 。
分治FFT
咕咕咕