链接
多项式乘法逆元
给你一个多项式 F ( x ) F(x) F(x),你要找出一个多项式 G ( x ) G(x) G(x)使得 F ( x ) G ( x ) = 1 F(x)G(x) = 1 F(x)G(x)=1
逆存在的充要条件是 F ( x ) F(x) F(x)的常数项部不等于 0 0 0
暴力求
一种很暴力的 O ( n 2 ) O(n^2) O(n2)做法是这样的:
首先 1 = g 0 f 0 1 = g_0 f_0 1=g0f0,所以 g 0 = f 0 − 1 g_0 = f_0^{-1} g0=f0−1;
然后 0 = g 0 f 1 + g 1 f 0 0 = g_0f_1 + g_1f_0 0=g0f1+g1f0,所以 g 1 = f 0 − 1 ( − g 0 f 1 ) g_1 = f_0^{-1}(-g_0f_1) g1=f0−1(−g0f1)
然后 0 = g 0 f 2 + g 1 f 1 + g 2 f 0 0= g_0f_2 + g_1f_1 + g_2f_0 0=g0f2+g1f1+g2f0,所以 g 2 = g 0 − 1 ( − g 0 f 2 − g 1 f 1 ) g_2 = g_0^{-1}(-g_0f_2-g_1f_1) g2=g0−1(−g0f2−g1f1)
快速求
现在普遍使用的是一个迭代算法,假设我已经知道了 g 0 , g 1 , … , g n − 1 g_0,g_1,\dots,g_{n-1} g0,g1,…,gn−1
假设已知多项式 H ( x ) H(x) H(x), h 0 = g 0 , h 1 = g 1 , … , h n − 1 = g n − 1 , h n = 0 , h n + 1 = 0 , h n + 2 = 0 , … h_0=g_0,h_1=g_1,\dots,h_{n-1}=g_{n-1},h_n=0,h_{n+1}=0,h_{n+2}=0,\dots h0=g0,h1=g1,…,hn−1=gn−1,hn=0,hn+1=0,hn+2=0,…
那么显然 F ( x ) H ( x ) F(x)H(x) F(x)H(x)的前 n n n个系数为 1 , 0 , 0 , 0 , … , 0 1,0,0,0,\dots,0 1,0,0,0,…,0,但是后面的系数不一定是 0 0 0
现在我需要继续推出 H ( x ) H(x) H(x)后面的系数
因为 H ( x ) − G ( x ) H(x)-G(x) H(x)−G(x)的前 n n n个系数都是 0 0 0,所以 ( H ( x ) − G ( x ) ) 2 (H(x)-G(x))^2 (H(x)−G(x))2的前 2 n 2n 2n项系数都是 0 0 0,所以 H 2 ( x ) + G 2 ( x ) − 2 H ( x ) G ( x ) H^2(x)+G^2(x)-2H(x)G(x) H2(x)+G2(x)−2H(x)G(x)的前 2 n 2n 2n项系数都是 0 0 0
给这个东西乘以 F 2 ( x ) F^2(x) F2(x),得到 H 2 ( x ) F 2 ( x ) + G 2 ( x ) F 2 ( x ) − 2 H ( x ) G ( x ) F 2 ( x ) H^2(x)F^2(x)+G^2(x)F^2(x)-2H(x)G(x)F^2(x) H2(x)F2(x)+G2(x)F2(x)−2H(x)G(x)F2(x)的前 2 n 2n 2n项系数都为 0 0 0
而 F ( x ) G ( x ) = 1 F(x)G(x)=1 F(x)G(x)=1,所以 H 2 ( x ) F 2 ( x ) + 1 − 2 H ( x ) F ( x ) H^2(x)F^2(x)+1-2H(x)F(x) H2(x)F2(x)+1−2H(x)F(x)的前 2 n 2n 2n项系数都为 0 0 0
即 F ( x ) ( 2 H ( x ) − F ( x ) H 2 ( x ) ) − 1 F(x)(2H(x)-F(x)H^2(x)) - 1 F(x)(2H(x)−F(x)H2(x))−1得前 2 n 2n 2n项系数都为 0 0 0,即 F ( x ) ( 2 H ( x ) − F ( x ) H 2 ( x ) ) F(x)(2H(x)-F(x)H^2(x)) F(x)(2H(x)−F(x)H2(x))得前 2 n 2n 2n项系数为 1 , 0 , 0 , 0 , . . . , 0 1,0,0,0,...,0 1,0,0,0,...,0
可以发现,本来 H ( x ) H(x) H(x)只能让 F ( x ) H ( x ) F(x)H(x) F(x)H(x)的前 n n n项系数为 1 , 0 , 0 , … 1,0,0,\dots 1,0,0,…,但是现在我找到了 ( 2 H ( x ) − F ( x ) H 2 ( x ) ) (2H(x)-F(x)H^2(x)) (2H(x)−F(x)H2(x)),乘以 F ( x ) F(x) F(x)之后可以让前 2 n 2n 2n项系数为 1 , 0 , 0 , … 1,0,0,\dots 1,0,0,…
上述推导用数学语言可以这样描述:
F ( x ) H ( x ) ≡ 1 ( m o d x n ) F ( x ) H ( x ) − 1 ≡ 0 ( m o d x n ) ( F ( x ) H ( x ) − 1 ) 2 ≡ 0 ( m o d x 2 n ) F 2 ( x ) H 2 ( x ) − 2 F ( x ) H ( x ) + 1 ≡ 0 ( m o d x 2 n ) F ( x ) ( 2 H ( x ) − F ( x ) H 2 ( x ) ) ≡ 1 ( m o d x 2 n ) F(x)H(x) \equiv 1 (\mod x^n) \\ F(x)H(x)-1 \equiv 0 (\mod x^n) \\ (F(x)H(x)-1)^2 \equiv 0 (\mod x^{2n}) \\ F^2(x)H^2(x) -2F(x)H(x) + 1 \equiv 0 (\mod x^{2n}) \\ F(x)(2H(x)-F(x)H^2(x)) \equiv 1 (\mod x^{2n}) F(x)H(x)≡1(modxn)F(x)H(x)−1≡0(modxn)(F(x)H(x)−1)2≡0(modx2n)F2(x)H2(x)−2F(x)H(x)+1≡0(modx2n)F(x)(2H(x)−F(x)H2(x))≡1(modx2n)
代码
struct Formal_Power_Series_inv
{
ll a[maxn], b[maxn], n, A[maxn], B[maxn];
void run()
{
ll i, now, N;
b[0]=em.inv(a[0],mod);
ntt.init(n), N=ntt.n;
for(now=2;now<=N;now<<=1)
{
rep(i,0,now-1)A[i]=a[i], B[i]=b[i];
ntt.init(2*now-1);
ntt.ntt(A,1), ntt.ntt(B,1);
rep(i,0,ntt.n-1)B[i]=B[i]*B[i]%mod*A[i]%mod;
ntt.ntt(B,-1);
rep(i,0,now-1)b[i]=(2*b[i]-B[i])%mod;
}
}
}fpsi;