1. 程式人生 > 實用技巧 >洛谷P4238 【模板】多項式乘法逆

洛谷P4238 【模板】多項式乘法逆

https://www.luogu.com.cn/problem/P4238

#include<cstdio>
#include<algorithm>

using namespace std;

#define N 300001

const int mod=998244353;
const int g=3;

int n;
long long a[N],b[N],c[N];
int rev[N];

long long poww(long long p,long long q)
{
    long long an=1;
    for(;q;q>>=1,p=p*p%mod)
        
if(q&1) an=an*p%mod; return an; } void ntt(long long *h,int m,int f) { for(int i=0;i<m;++i) if(i<rev[i]) swap(h[i],h[rev[i]]); for(int i=1;i<m;i<<=1) { long long wn=poww(g,(mod-1)/(i*2)); if(f<0) wn=poww(wn,mod-2); for(int j=0,p=i<<1
;j<m;j+=p) { long long w=1; for(int k=0;k<i;++k,w=w*wn%mod) { long long x=h[j+k],y=w*h[j+k+i]%mod; h[j+k]=(x+y)%mod; h[j+k+i]=(x-y+mod)%mod; } } } if(f<0) { long long inv=poww(m,mod-2
); for(int i=0;i<m;++i) h[i]=h[i]*inv%mod; } } void work(int m,long long *b) { if(m==1) { b[0]=poww(a[0],mod-2); return; } work(m+1>>1,b); int len=1,nn,mm=2*m-1; for(nn=0;len<mm;len<<=1,++nn); for(int i=1;i<len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<nn-1); for(int i=0;i<m;++i) c[i]=a[i]; for(int i=m;i<len;++i) c[i]=0; ntt(c,len,1); ntt(b,len,1); for(int i=0;i<len;++i) b[i]=((2-b[i]*c[i])%mod+mod)%mod*b[i]%mod; ntt(b,len,-1); for(int i=m;i<len;++i) b[i]=0; } int main() { scanf("%d",&n); for(int i=0;i<n;++i) scanf("%lld",&a[i]); work(n,b); for(int i=0;i<n;++i) printf("%lld ",b[i]); }