问题描述
给定一个多项式 $F(x)$,请求出一个多项式 $G(x)$,满足 $ F(x) * G(x) equiv 1(mod x^n)$。系数对998244353998244353取模。
分析
理论基础
这是一个递推式且呈平方倍增加,就可以用倍增求多项式逆元,从 $x^1$ 开始推至 $x^{2^m}(2^m geq n)$即可。初值 $B = A(0)^{-1}$。
利用NTT可以将多项式乘法优化至 $nlog_2n$,利用主定理计算得总时间复杂度为 $O(nlog_2n)$。
代码:
#include<bits/stdc++.h> using namespace std; int read() { int q=0;char ch=' '; while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar(); return q; } #define RI register int typedef long long ll; const int mod=998244353,G=3,N=4*100000 + 10; //同NTT,需要4倍的空间 int n; int a[N],b[N],c[N],rev[N]; inline int qpow(int x,int k) { int ans=1; while(k) { if(k&1) ans=(ll)ans*x%mod; x=(ll)x*x%mod,k>>=1; } return ans; } void NTT(int *a,int n,int x) { for(RI i=0;i<n;++i) if(i<rev[i]) swap(a[i],a[rev[i]]); for(RI i=1;i<n;i<<=1) { RI gn=qpow(G,(mod-1)/(i<<1)); for(RI j=0;j<n;j+=(i<<1)) { RI t1,t2,g=1; for(RI k=0;k<i;++k,g=1LL*g*gn%mod) { t1=a[j+k],t2=1LL*g*a[j+k+i]%mod; a[j+k]=(t1+t2)%mod,a[j+k+i]=(t1-t2+mod)%mod; } } } if(x==1) return; int ny=qpow(n,mod-2); reverse(a+1,a+n); for(RI i=0;i<n;++i) a[i]=1LL*a[i]*ny%mod; } void work(int deg,int *a,int *b) { if(deg==1) {b[0]=qpow(a[0],mod-2);return;} work((deg+1)>>1,a,b); RI len=0,orz=1; while(orz<(deg<<1)) orz<<=1,++len; for(RI i=1;i<orz;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1)); for(RI i=0;i<deg;++i) c[i]=a[i]; //C=A for(RI i=deg;i<orz;++i) c[i]=0; NTT(c,orz,1),NTT(b,orz,1); for(RI i=0;i<orz;++i) b[i]=1LL*(2-1LL*c[i]*b[i]%mod+mod)%mod*b[i]%mod; //B = 2B-2CB^2 = (2-CB)B NTT(b,orz,-1); for(RI i=deg;i<orz;++i) b[i]=0; } int main() { n=read(); for(RI i=0;i<n;++i) a[i]=read(); work(n,a,b); for(RI i=0;i<n;++i) printf("%d ",b[i]); return 0; }