[模板][P4238]多项式求逆
NTT多项式求逆模板,详见代码
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=5e5+5,mod=998244353,G=3,Gi=332748118;
int n,l,lim=1,a[mxn],b[mxn],c[mxn],r[mxn];
inline int read() {
char c=getchar(); int x=0,f=1;
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
return x*f;
}
inline int chkmax(int &x,int y) {if(x<y) x=y;}
inline int chkmin(int &x,int y) {if(x>y) x=y;}
struct ed {
int to,nxt;
}t[mxn<<1];
int qpow(int a,int b)
{
int res=1,base=a;
while(b) {
if(b&1) res=1ll*res*base%mod;
base=1ll*base*base%mod;
b>>=1;
}
return res;
}
void NTT(int *p,int opt)
{
for(int i=0;i<lim;++i)
if(i<r[i]) swap(p[i],p[r[i]]);
for(int mid=1;mid<lim;mid<<=1) {
int wn=qpow(opt==1?G:Gi,(mod-1)/(mid<<1));
for(int len=mid<<1,j=0;j<lim;j+=len) {
int w=1;
for(int k=0;k<mid;++k,w=1ll*w*wn%mod) {
int x=p[j+k],y=1ll*w*p[j+mid+k]%mod;
p[j+k]=(x+y)%mod; p[j+mid+k]=(x-y+mod)%mod;
}
}
}
}
void solve(int deg,int *a,int *b)
{
if(deg==1) {b[0]=qpow(a[0],mod-2); return ;}
solve((deg+1)>>1,a,b); lim=1,l=0;
while(lim<=2*deg) lim<<=1,++l;
for(int i=0;i<lim;++i)
r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<deg;++i) c[i]=a[i];
for(int i=deg;i<lim;++i) c[i]=0;
NTT(b,1); NTT(c,1);
for(int i=0;i<lim;++i)
b[i]=1ll*(2ll-1ll*c[i]*b[i]%mod+mod)%mod*b[i]%mod;
NTT(b,-1); int inv=qpow(lim,mod-2);
for(int i=0;i<lim;++i) b[i]=1ll*b[i]*inv%mod;
for(int i=deg;i<lim;++i) b[i]=0;
}
int main()
{
n=read();
for(int i=0;i<n;++i) a[i]=read();
solve(n,a,b);
for(int i=0;i<n;++i) printf("%d ",b[i]);
return 0;
}