因为本来数学就好弱,所以就一边做题一边学,边记录一下吧。
假设现在给定一个多项式 A ,要求多项式 B 使得 A∗B≡1(mod xn)
首先对于多项式的题目,思路大概有三种:
1. 倍增
2. 分治
3. 卡常
求逆元用的是倍增的思想。
假设我们当前求出了 B0,A∗B0≡1(mod x⌈n2⌉)
那么显然,由于 A∗B≡1(mod xn) ,则 A∗B≡1(mod x⌈n2⌉)
所以 B−B0≡0(mod x⌈n2⌉)
(B−B0)2≡0(mod xn)
B2≡B0(2B−B0)(mod xn)
两边同时乘以 A ,则
B≡B0(2−B0∗A)(mod xn)
那么 B 就可以计出来了。
时间复杂度 f(n)=f(n/2)+nlogn=O(nlogn)
设现在有两个多项式 A,B ,其中 Deg(A)=n,Deg(B)=m,n≥m>0 。
我们要求出多项式 D,M ,使得 A=B∗D+M ,且 Deg(D)=n−m,Deg(M)<m
先写出来
A(x)=B(x)∗D(x)+M(x)
A(1x)=B(1x)∗D(1x)+M(1x)
A(x) 的倒置 Ar(x)=xnA(1x)
我们对等式两边同乘 xn ,则
xnA(1x)=xnB(1x)∗D(1x)+xnM(1x)
xnA(1x)=xmB(1x)∗xn−mD(1x)+xnM(1x)
Ar(x)=Br(x)Dr(x)+xnM(1x)
我们将这条式子放在 mod xn−m+1 意义下看,
Ar(x)≡Br(x)Dr(x)+xnM(1x)(mod xn−m+1)
因为 n≥n−m+1 ,所以 xnM(1x)≡0(mod xn−m+1)
所以
Ar(x)≡Br(x)Dr(x)(mod xn−m+1)
Dr(x)≡Ar(x)∗[Br(x)]−1(mod xn−m+1)
由于 Deg(D)=n−m<n−m+1 ,所以直接相乘得出来的就是原来的 Dr
那么我们就可以得到 D 了,同理也可以得到 M 。
复杂度为计算逆元以及乘法的复杂度,所以也是 O(nlogn) 的。只是常数大了一点点。
设一个数列 A 为 k 齐次线性递推关系,当且仅当其满足
∀i≥k,Ai=∑kj=1Ai−j∗Cj
其中 C 为给定的一个 k 项的数列。
要快速求出 An ,一个经典的做法就是构造一个 k∗k 的矩阵,然后矩阵快速幂。这样的复杂度是 O(k3logn) 的。
但事实上复杂度能做得更好。
设多项式 M(x)=xk−C1xk−1−C2xk−2−⋯−Ck 。这个多项式也被称为 A 的特征多项式。
设 A 的生成函数为 A(x)=∑i≥0Ai∗xi 。
那么我们可以发现的是
P(x)=A(x)−C1∗x∗A(x)−C2∗x2∗A(x)−⋯−Ck∗xk∗A(x)=A(x)∗Mr(x)
满足 Deg(P)<k ,因为后面的项都被约掉了。
因此, A(x)=P(x)Mr(x) 。
也就是说,一个 k 齐次线性递推关系的数列的生成函数,必然能表示成一个次数小于 k 的多项式除以一个次数为 k 的多项式的形式。
同理,对于一个分式 P(x)M(x) ,若满足 M(x)|P(x),Deg(M)>Deg(P) ,则其必然为一个 Deg(M) 齐次线性递推关系的数列的生成函数。
但只有这些还不够,有一个非常重要的定理。
若存在一个多项式 S ,设 Deg(S)=l ,满足 M|S ,则以 M 为特征多项式的数列 A 必然满足
设多项式 S(x)≡xN(mod M(x)) 。那么 xN−S(x) 必然能被 M(x) 整除。
由上面的定理可得
AN=∑k−1i=0Si∗Ai 。
那么现在的问题就是计算这个 S(x) 。一种暴力的做法就是用快速幂暴力乘,暴力取模,这样的复杂度是 O(k2logN) 的。
但我们上面已经讲了取模可以做到 O(NlogN) 。
那么计算 S 的复杂度就可以使 O(klogklogN) 。
给定一个多项式 F(x) ,以及若干个 xi ,让你求出 F(xi) 。
上面说过了多项式的题无非倍增或分治。这里就是分治。
设过程Solve (l,r,F) ,表示我们要计算出所有的 F(xi),i∈[l,r] ,并且 Deg(F)=O(r−l) 。
那么很显然,当 l=r 时,直接计算。
否则,我们设 mid=l+r2 。
构建两个多项式 M0,M1 ,分别满足
设 Q0,Q1 ,满足
则
我们将 xi,i∈[l,mid] 代入 F(x) ,可得 F(xi)=M0(xi)∗C0(xi)+Q0(xi) 。
又由于 M0(xi)=0 ,所以 F(xi)=Q0(xi) 。
对于 i∈[mid+1,r] 同理。
那么我们递归下去,Solve (l,mid,Q0) 以及Solve (mid+1,r,Q1) 即可。并且 Deg(Q0)=O(mid−l) 。
总的复杂度为 O(nlog2n)