多项式乘法逆
给你多项式 ,寻找一个多项式满足 。考虑倍增求解。 如果我们已知 ,而根据 。那么显然 ,两式相减那么 ,左右相减 。考虑左右都乘上一个 ,那么 移项 。那我们的递归出口为 。
代码
#include<bits/stdc++.h> using namespace std; #define int long long const int p = 998244353,Gi = 3,N = 2e6+100; #define LL long long int read() {int x;scanf("%lld",&x);return x;} int qpow(int a,int b) { int x = 1;for(;b;b >>= 1,a = 1LL * a * a % p) { if(b&1) x = 1LL * x * a % p; } return x; } int f[N],g[N],g2[N],r[N]; void ntt(int *a,int type,int limit) { for(int i = 0;i < limit;i++) if(i < r[i]) swap(a[i],a[r[i]]); for(int mid = 1;mid < limit;mid <<= 1) { int wn = qpow(Gi,(p-1)/(mid<<1)); for(int i = 0;i < limit;i+=(mid<<1)) { int w = 1; for(int j = 0;j < mid;j++,w = 1LL * w * wn % p) { int x = a[i + j],y = 1LL * w * a[i + j + mid] % p; a[i + j] = (x + y) % p; a[i + j + mid] = (x - y + p) % p; } } } if(type == -1) { int inv = qpow(limit,p-2); if(limit > 1) reverse(a+1,a+limit); for(int i = 0;i < limit;i++) a[i] = 1LL * a[i] * inv % p; } } void Inv(int *a,int *b,int deg) { if(deg == 1) {b[0] = qpow(a[0],p-2);return;} Inv(a,b,(deg+1)>>1); int L = 0,limit = 1; while(limit <= deg + deg - 2) limit <<= 1,L++; for(int i = 0;i < limit;i++) r[i] = (r[i>>1]>>1)|((i&1)<<L-1); for(int i = 0;i < deg;i++) g2[i] = a[i]; for(int i = deg;i < limit;i++) g2[i] = 0; ntt(g2,1,limit);ntt(b,1,limit); for(int i = 0;i < limit;i++) { b[i] = ((2LL - b[i] * g2[i] % p) + p) % p * b[i] % p; } ntt(b,-1,limit); for(int i = deg;i < limit;i++) b[i] = 0; } signed main() { int n = read() - 1; for(int i = 0;i <= n;i++) f[i] = read(); Inv(f,g,n+1); for(int i = 0;i <= n;i++) printf("%lld ",g[i]); printf("\n");return 0; }