多项式全家桶

【多项式求逆】

【整式取模】

定义单项式取模。

Cxkmodxn={0knCxkk<n

定义多项式取模为它的每一项取模相加。

可以看出,模 xn 相当于保留 0n1 次项。

【问题描述】

一般形式:已知多项式 A(x),C(x),求 B(x) 使 A(x)B(x)=C(x)(modxn)

特殊形式:已知多项式 A(x),求 D(x) 使 A(x)D(x)=1(modxn)

我们只需要解特殊形式,因为解出特殊形式的 D(x) 后,可以令 B(x)=D(x)C(x),一次卷积 O(nlogn) 即可。

【解法 - O(n2)

已知 A(x),求 B(x) 使 A(x)B(x)=1(modxn)

A,B 的系数为 A0An1,B0Bn1

首先要保证 A00,否则 A(x) 不可逆;然后可得 A0B0=1,可以解 B0

然后 A1B0+A0B1=0,可以解出 B1 …… 如此循环,可以 O(n2) 求解。

【解法 - O(nlogn)

注意到如果 A(x)B(x)=1(modxn),则 A(x)B(x)=1(modxn1)。所以我们可以增大 n,这样的解也是符合要求的解。

n=2k,方便我们用倍增的方法优化。
假设已知 B(x) 满足 A(x)B(x)=1(modxm),怎么求得 B2(x) 满足 A(x)B2(x)=1(modx2m)

AB1=0(modxm)(AB1)2=0(modx2m)A2B22AB+1=0(modx2m)2ABA2B2=1(modx2m)A(2BAB2)=1(modx2m)

因此 B2(x)=2B(x)A(x)B(x)2。从 A(x),B(x)B2(x),只需要做两次多项式乘法和一次多项式减法,复杂度 O(nlogn)
但是倍增也有一个 log 啊?怎么是 O(nlogn) 呢?

因为对于一个 m,我们只保留多项式前 m 项即可,不用保留 n 项。因此复杂度应该是 O(nlogn+n2logn+n4logn+)=O(nlogn)

可以把求逆看作除法。

【多项式开方】

【多项式带余除法】

给定 A(x),B(x),找 C(x),R(x) 使得 A(x)=B(x)C(x)+R(x),要求 degR(x)<degB(x)
不妨 degAdegB,不然直接令 C(x)=0,R(x)=A(x)。记 n=degA,m=degB
为了下面方便,把 R(x) 最高次不断补 0,直到 degR=m1

定义一个操作 RAR(x)=xnA(1x)
AR 的作用其实就是把 A 的系数翻转(Reverse)了。可以手算一下。

A(x)=B(x)C(x)+R(x)A(1x)=B(1x)C(1x)+R(1x)xnA(1x)=xnB(1x)C(1x)+xnR(1x)xnA(1x)=xmB(1x)xnmC(1x)+xm1R(1x)xnm+1AR(x)=BR(x)CR(x)+RR(x)xnm+1注意这里的 Reverse(R) 是从 m-1 次项开始翻转,是补足之后的AR(x)=BR(x)CR(x)(modxnm+1)

用多项式求逆解 CR(x)。为什么这里的 BR(x) 是一定有逆的?因为 B(x) 的最高次项的系数一定不是 0,否则 degBm 矛盾。因此 BR(x) 的常数项非 0。求逆复杂度 O(nlogn)

因为 CR(x) 就是 C(x) 的系数翻转。所以 O(n) 可得 C(x)。而 R(x)=A(x)B(x)C(x),一次卷积即可,复杂度 O(nlogn)

总复杂度 O(nlogn)

【例题】

  • HDU5730

1×i 的骨牌种类数为 ai。要用若干骨牌覆盖 1×n。问方案数。ai,n105

法一:令 A(x)=i1aixi。用 k 个骨牌覆盖的方案数为 [xn]Ak(x)ans=k0[xn]Ak(x)=[xn]k0Ak(x)=[xn]11A(x)
O(n) 算出来 A(x),然后 O(1)1A(x),然后 O(nlogn)1A(x)modxn+1 的逆。

法二:考虑 DP。
fn=i=0nfniai。是卷积的形式。可以推出 F=F×A+1。这个 +1 是因为 n=0a0=0,但是 f0=1
F=11A,求逆。

  • P4841 城市规划

n 个点有标号连通图个数。n2e5

法一:EGF。
P(x) 为 "n 个点有标号图个数" 的 EGF,Q(x) 为 "n 个点有标号连通图个数" 的 EGF。有 P(x)=expQ(x),则 Q(x)=lnP(x)。虽然 ln 还不知道,但是 O(nlogn) 可解。

法二:基于求逆。
pn=2(n2)n 个点有标号图数量,fn 为答案。枚举 1 所在连通块的大小 k
pn=k=1n(n1k1)fkpnk,套路把二项式系数拆开放。pn(n1)!=k=1nfk(k1)!pnk(nk)!

已经是类似卷积的形式。考虑三个多项式 P1(x)=n1pn(n1)!xnF(x)=k1fk(k1)!xk,P2(x)=n0pnn!xn。可以观察到 P1(x)=F(x)P2(x),因为 pn 是已知的,所以 P1(x),P2(x) 已知。一次求逆即可求出 F(x)。因为我们要求 xn 的系数,模数取 xn+1 即可。

【多项式 lnexp

重要公式: ln(1x)=i=11ixi

证明:当 x=0 时相等。而两侧导数相等。所以相等。注意这里有个负号

可以看出,当 A(x) 的常数项为 1ln(A(x)) 不含常数项。
(求 ln(A(x)),令 A(x)=1B(x)ln(1B(x)) 可求)

重要公式exp(A(x))=i0Ai(x)i!。即泰勒展开式。

ln

给定多项式 A(x),保证常数项 =1,求 G(x)=ln(A(x))modxn

因为 A0=1,所以 G0=0
G(x)=ln(A(x)),G(x)=A(x)A(x)(导数)。

大体思路是求 G(x)%xn1,然后已知导数可以还原出 G(x)x1xn 项系数。而 G0=0 是已知的。

于是我们目标求 A(x)A(x)modxn1。而 A(x) 已知,进而 A(x) 已知。所以 A(x)A(x)modxn1 可以用求逆 O(nlogn) 求得。


如果首项不是 1 怎么办?首先 ln(0) 是没有定义的,其次可以提取公因式使首项为 1

ln(A(x)B(x))=ln(A(x))+ln(B(x))

exp

exp(A(x))=eA(x)=i0A(x)ii!

给定常数项为 0n1 次多项式 A(x),求 exp(A(x))。(如果常数项非 0,可以把常数项单独拆出来。例如 e4+x=e4ex

B(x)=eA(x)f0(x)=B(x)(modxn)。还是倍增的思路,考虑如何求出 f1(x)=B(x)(modx2n)

这里用到泰勒展开。即 g(x)=g(x0)+g(x0)(xx0)+12!g(x0)(xx0)2+

xB(x),x0f0(x),再模 x2n。因为 (B(x)f0(x))2 及以后模 x2n 都变成 0 了。所以 g(B(x))=g(f0(x))+g(f0(x))(B(x)f0(x))

然后我们令 g(x)=lnx,得到 lnB(x)=A(x)=lnf0(x)+1f0(x)(B(x)f0(x))(modx2n)

可推出:

B(x)=f0(x)(A(x)lnf0(x)+1)(modx2n)

因此 f1(x)=f0(x)(A(x)lnf0(x)+1)。不断倍增直到模数足够。
然后 B(x)=f(x)(A(x)lnf(x)+1)(modx2n),可求出 B(x)

细节:记 N 为将 n 扩充为 2 的幂后的 nf0(x)N 次,A(x)lnf0(x)+1N 次,则 f1(x)2N 次。为了确定 2N 次多项式的系数,需要 2N 个点值,而 N2n,所以需要 4n 个点值,所以 FFT 设置单位根要用 ε4n

【例题】

  • P4389 付公主的背包

i=1n(11xi)ai(modxN+1)
注意 n 是物品个数,N 是目标容积。

要把次方拿下来,可以用 ln+exp

=exp(ln(i=1n(11xi)ai))=exp(ln(i=1n(1xi)ai))=exp(i=1nailn(1xi))=exp(i=1nai(j1xijj))=exp(i=1naij=1[Ni]xijj)(modxN+1)

复杂度?exp 内部是调和级数的 O(nlogn)exp 也是 O(nlogn) 的。

  • 有限制的置换计数

给定一个集合 S,问有多少个 n 阶置换,每个轮换大小都属于集合 S

可以看作图计数(若干个环)。这个和城市规划相反,连通的很好计数,不连通的反而不好算。
用 EGF 即可。

【多项式快速幂】

给定 f(x)。求 fk(x)modxn

如果快速幂,复杂度 O(nlogklogn),但可以优化到 O(nlogn)

要把次方拿下来,可以 ln+exp

假设 f(x) 常数项为 1fk(x)=exp(lnfk(x))=exp(klnf(x))lnf(x) 因为常数项 1 很好求。

如果 f(x)=axd(1+?x?+?x?+)=axdg(x),则 fk(x)=aKxkdgk(x)gk(x) 用上面的方法求。

【多项式多点点值】

f(x) 已知,求 fx0xn1 的值。O(nlog2n)

Pl,r(x)=i=lr(xxi)fl,r(x)=f(x)%Pl,r(x)

(多项式模多项式就是带余除法)

fi,i(x)=f(x)%(xxi)f(x)=(xxi)Q(x)+fi,i(x)

f(xi)=fi,i(x)

总思路是分治,先求 f1,n,再求 f1,n/2,fn/2+1,n ……

关键:已知 fl,r(x),求 fl,m(x)fm+1,r(x)。这两者是对称的,只研究怎么求前者。

fl,r(x)=f(x)%pl,r(x)

fl,m(x)=f(x)%pl,m(x)

注意到 pl,m(x)pl,r(x) 的因式,所以 f(x)%pl,m(x)=(f(x)%pl,r(x))%pl,m(x)=fl,r(x)%pl,m(x)

如果 pl,m(x) 已知,可以 O(nlogn) 取模求出。每层复杂度 O(nlogn),共 O(nlog2n)

如何预处理 Pl,m(x)?分治树从底向上。

【多项式多点插值】

还是拉格朗日插值法。先把不优化的 O(n2) 版本放出来。

可以优化到 O(nlog2n)

先求分母。定义 M(x)=i=0n1(xxi)。则 F(x)i 项分母为 M(x)xxix=xi 的值。

M(x),xxix=xi 时都为 0。使用洛必达法则M(x)xxi=M(x)1=M(x),即求 M(x)x=xi 的值。

于是先求 M(x),可以 O(nlog2n) 分治求;然后 O(n)M(x);最后用上面的点值求出 M(x)x0xn1 的值,即可得到 i=0n1 的分母。

求出分母后,令 Vi 为第 i 个的分母乘以 yiF(x)=i=0n1Viji(xxj)。这里 Vi 是已经 O(nlog2n) 求出来的了。

这个式子直接循环还是至少平方级别。需要简化。

F(x)=i=0n1Vij=0n1(xxj)[ji]

定义一个 L(x)=j=0n/21(xxj),R(x)=j=n/2n1(xxj)

F(x)=[i=0n/21Vi(j=0n/21(xxj)[ji])R(x)]+[i=n/2n1Vi(j=n/2n1(xxj)[ji])L(x)]

(因为当 i=0n/21j=n/2n1[ji] 肯定是 1

F(x)=R(x)i=0n/21Vij=0n/21(xxj)[ji]+L(x)i=n/2n1Vij=n/2n1(xxj)[ji]

这拆出来的两项和 F(x) 原本的形式一样,只是规模减半了。所以可以分治下去。合并的时候 R(x)L(x) 做乘法再相加即可。合并复杂度 O(nlogn),总复杂度 O(nlog2n)

对于 L(x),R(x) 也要预处理,和点值的 pl,r(x) 处理方法一样。

【例题】

  • UOJ182 "a1+b"

给定 x1xnn1e5m6e4 个操作。每个操作要么全体加 C,要么全体求逆。这里一切运算均在模 998244353 意义下进行。每次操作后输出所有 xi 之和。

结论:在第 i 轮操作后,所有 xj 形式都是 aixj+bicixj+di

即求 j=1naixj+bicixj+di

分子的次数等于分母,可以做分离常数,=eicixj+di+ci。如果 ci=0,可以立刻求出来;否则上下同时除以 ci=uixj+ti+ci。然后可以把 ui 统一提到求和符号外面去,=ui1xj+ti+ci

上面所有只和 i 相关的都能求出来,然后怎么做?

定义 f(t)=i1xi+t。预先把 m 次操作后的 ti 都算出来,我们要求 f(t)t1tm 的值。

但是 f(t) 不是多项式。直接通分,分母 Q(t)=(t+x1)(t+xn)。观察到分子 P(t) 恰好是 Q(t) 的导数(链式法则)。

Q(t) 可以 O(nlog2n) 求,Q(t) 可以从 Q(t) 求。对 Q(t),Q(t) 多点求值即可。

posted @   FLY_lai  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示