多项式全家桶

求逆

考虑倍增。

若已经求出 A×B1(modxn),我们希望求出 B 使得 A×B1(modx2n)

有:

BB0(modxn)

(BB)20(modx2n)

B22BB+B20(modx2n)

两边同乘 A,有:

B2B+AB20(modx2n)

所以:

B2BAB2(modx2n)

注意应该倍增到最小的 2t 使得 2tn

时间复杂度 O((n+n2+n4+)logn)=O(nlogn)

带余除法

比较智慧。

考虑定义一个操作 AR(x)=A(1x)=i=0naixni。其实就是把系数翻转。

那么:

F(x)Q(x)G(x)+R(x)(modxn)

F(1x)Q(1x)G(1x)+R(1x)(modxn)

xnF(1x)xnmQ(1x)xmG(1x)+xnR(1x)(modxn)

FR(x)QR(x)GR(x)+xnm+1RR(x)(modxn)

FR(x)QR(x)GR(x)(modxnm)

QR(x)FR(x)GR(x)1(modxnm)

注意到 Q(x) 的最高项次数恰为 nm,所以这样即可求得 Q(x),进而求出 R(x)

时间复杂度 O(nlogn)

ln

考虑利用多项式求导,有:

B(x)lnA(x)(modxn)

B(x)A(x)A(x)(modxn)

这样就能求出 B(x),进而求出 B(x)

时间复杂度 O(nlogn)

exp

考虑泰勒展开。对于一个光滑函数 g(x),我们有:

g(x)=g(x0)+11!g(x0)(xx0)+12!g(x0)(xx0)2+

考虑倍增。假设我们已经求出了 B0(x) 使得 A(x)lnB0(x)(modxn),我们现在希望求出 B(x) 使得 A(x)lnB(x)(modx2n)。那么令 glnxB(x)x0B0(x)

注意到 B(x)B0(x)(modxn),所以 (B(x)B0(x))20(modx2n)。所以有:

ln(B(x))ln(B0(x))+B(x)B0(x)B0(x)(modx2n)

B0(x)(A(x)ln(B0(x))+1)B(x)(modx2n)

做一次 ln 和乘法即可。

注意一些实现细节,比如 ln(B0(x)) 应该在 modx2n 意义下算。

时间复杂度 O((n+n2+n4+)logn)=O(nlogn)

快速幂

B(x)A(x)k(modxn)

lnB(x)klnA(x)(modxn)

B(x)eklnA(x)(modxn)

所以先 lnexp 即可。

注意为了保证 [x0]A(x)=1 需要先提公因式 axp

开方

相当于 k12 的快速幂。

为了保证 [x0]A(x)=1 仍然提公因数 a(因为这项一定不是 0)。那么求一个 a 的二次剩余再乘回去即可。

多点求值

发现 F(x0)=F(x)mod(xx0)。因为 F(x)=Q(x)G(x)+R(x),而且 G(x0)=0

考虑分治求 F(x)modi=lr(xai)。每次把 F(x)i=lr(xai) 取模即可。这样时间复杂度是 O(nlog2n),但是因为每次递归都要多项式取模所以常数很大。

发现因为余数只有常数项,并且 R(x)=F(x)Q(x)G(x),所以我们也只用关心 F(x),G(x),Q(x) 的常数项,即 FR(x),GR(x),QR(x)n1 次项。

所以我们一开始先令 G(x)=i=1n(xai) 并算出 QR(x),然后分治左区间则乘上右半边的乘积,分治右区间则乘上左半边的乘积。并且注意到递归到 [l,r] 后之后乘的多项式次数 <rl+1,所以可以只保留后面 rl+1 项,这样复杂度就对了,还是 O(nlog2n)

快速插值

考虑拉格朗日插值,答案即为

i=1nyijixxjxixj

先考虑每个 i 对应的分母 zi。设 F(x)=i=1n(xxi),相当于要算 F(x)xxi 代入 xi 后的值。但是此时分子和分母都是 0。根据洛必达法则,此时可以算 F(x)(xxi)=F(x) 代入 xi 后的值。于是多点求值即可。

再考虑算整个式子。仍然可以分治,分治的时候算 i=lryiziljrji(xxj)。只需要左边的答案乘上右半边区间多项式的乘积,加上右边的答案乘上左半边区间多项式的乘积即可。时间复杂度 O(nlog2n)

常系数齐次线性递推

考虑构造矩阵 M,其中 M0,i=ai+1Mi+1,i=1,其余位置为 0。那么:

[fn+k1fn+k2fn]=Mn[fk1fk2f0]

M 的特征多项式为 φ(x)=xka1xk1a2xk2akx0

xn=Q(x)φ(x)+R(x),那么 Mn=Q(M)φ(M)+R(M)。又因为由 Cayley-Hamilton 定理得 φ(M)=0,所以 Mn=R(M)

R(x)=i=0k1rixi,列向量 F=[fk1fk2f0]。那么:

Mn=i=0k1riMiMnF=i=0k1ri(MiF)(MnF)k1=i=0k1ri(MiF)k1fn=i=0k1rifi

于是剩下的问题是求 R(x),也就是 xnmodφ(x)。直接多项式快速幂即可,每次次数超过 k 了就对 φ(x) 取模。

时间复杂度 O(klogklogn)

posted @   zltzlt  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示