多项式的这些东西我都是从这位大佬的博客中学会的…确实写得很好
多项式求逆元我用了大佬的
O(nlogn)
O
(
n
log
n
)
的倍增算法
A(x)B(x)≡1(modx⌈x2⌉)
A
(
x
)
B
(
x
)
≡
1
(
mod
x
⌈
x
2
⌉
)
A(x)A−1(x)≡1(modx⌈x2⌉)
A
(
x
)
A
−
1
(
x
)
≡
1
(
mod
x
⌈
x
2
⌉
)
合并,
A(x)(B(x)−A−1(x))≡0(modx⌈x2⌉)
A
(
x
)
(
B
(
x
)
−
A
−
1
(
x
)
)
≡
0
(
mod
x
⌈
x
2
⌉
)
因为 A(x) A ( x ) 不为零,
(B(x)−A−1(x))≡0(modx⌈x2⌉)
(
B
(
x
)
−
A
−
1
(
x
)
)
≡
0
(
mod
x
⌈
x
2
⌉
)
平方,
B(x)2+A−2(x)−2B(x)A−1(x)≡0(modx)
B
(
x
)
2
+
A
−
2
(
x
)
−
2
B
(
x
)
A
−
1
(
x
)
≡
0
(
mod
x
)
同乘 A(x) A ( x ) ,
B(x)2A(x)+A−1(x)−2B(x)≡0(modx)
B
(
x
)
2
A
(
x
)
+
A
−
1
(
x
)
−
2
B
(
x
)
≡
0
(
mod
x
)
移项,
A−1(x)≡B(x)(2−B(x)×A(x))(modx)
A
−
1
(
x
)
≡
B
(
x
)
(
2
−
B
(
x
)
×
A
(
x
)
)
(
mod
x
)
再用NTT解决
#include<bits/stdc++.h>
#define il inline
#define swap(x,y) (x^=y,y^=x,x^=y)
#define p(a,b) 1ll*a*b%mo
#define add(a,b) (a+b>=mo?a+b-mo:a+b)
#define dec(a,b) (a-b<0?a-b+mo:a-b)
using namespace std;
const int N=(1<<21)+5,mo=998244353,G=3,Gi=332748118;
#define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
il int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
return x*f;
}
char sr[1<<21],z[20];int C=-1,Z;
il void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
il void print(int x){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]=' ';
}
il int qpow(int a,int k){
int base=1;
while(k){
if(k&1) base=p(a,base);
a=p(a,a);k>>=1;
}
return base%mo;
}
int n,r[N],x[N],y[N],A[N],B[N],Og[N];
il void NTT(int *a,int type,int len){
int limit=1,L=0;
while(limit<len) 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<limit;++i) if(i<r[i]) swap(a[i],a[r[i]]);
for(int mid=1;mid<limit;mid<<=1){
int R=mid<<1;
int W=qpow(G,(mo-1)/R);Og[0]=1;
for(int j=1;j<mid;++j) Og[j]=p(Og[j-1],W);
for(int j=0;j<limit;j+=R){
for(int k=0;k<mid;++k){
const int x=a[j+k],y=p(Og[k],a[j+k+mid]);
a[j+k]=add(x,y),a[j+k+mid]=dec(x,y);
}
}
}
if(type==-1){
reverse(A+1,A+limit+1);
for(int i=0,inv=qpow(len,mo-2);i<limit;++i) A[i]=1ll*A[i]*inv%mo;
}
}
void inv(int *a,int *b,int len){
if(len==1){
b[0]=qpow(a[0],mo-2);
return ;
}
inv(a,b,len>>1);
for(int i=0;i<len;++i) A[i]=a[i],B[i]=b[i];
NTT(A,1,len<<1);NTT(B,1,len<<1);
for(int i=0;i<(len<<1);++i) A[i]=p(p(A[i],B[i]),B[i]) ;
NTT(A,-1,len<<1);
for(int i=0;i<len;++i) b[i]=(1ll*(b[i]<<1)%mo+mo-A[i])%mo;
}
int main(){
n=read();
for(int i=0;i<n;++i) x[i]=(read()+mo)%mo;
int Len=1;for(;Len<n;Len<<=1);inv(x,y,Len);
for(int i=0;i<n;++i) print(y[i]);Ot();
return 0;
}