题解 P4726 【【模板】多项式指数函数】
发一个分治NTT的题解。如果想要看一个log的正解请参考其他dalao的代码。
题目要求的是
时间复杂度
代码如下(我的NTT写法比较短):
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll lg=18,N=1<<lg,mod=998244353;
int n;
ll f[N],g[N],rev[N],w[N],c[N],d[N];
ll po(ll a,ll b){
ll r=1;for(;b;b>>=1,(a*=a)%=mod)if(b&1)(r*=a)%=mod;
return r;
}
void FFT(ll *a,int lg){
for(int i=0;i<(1<<lg);i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=0;i<lg;i++)
for(int j=0;j<(1<<lg);j++)if(j&1<<i){
ll x=j^1<<i,l=a[x],r=a[j]*w[(j&(1<<i)-1)<<lg-1-i]%mod;
a[x]=(l+r)%mod,a[j]=(l+mod-r)%mod;
}
}
void work(int l,int r){ //此处是左闭右开区间[l,r)
if(l+1==r){
if(l)(f[l]*=po(l,mod-2))%=mod;else f[l]=1;
return;
}
int mid=l+r>>1,_lg,n;
work(l,mid);
for(_lg=0;1<<_lg<r-l-1;_lg++);
n=1<<_lg;
for(int i=0;i<n;i++)
c[i]=d[i]=0,w[i]=po(3,1ll*(mod-1)*i/n),
rev[i]=rev[i/2]/2|(i&1)<<_lg-1;
for(int i=0;i<mid-l;i++)c[i]=f[i+l];
for(int i=0;i<r-l-1;i++)d[i]=g[i];
FFT(c,_lg),FFT(d,_lg);
for(int i=0;i<n;i++)(c[i]*=d[i])%=mod,w[i]=po(w[i],mod-2);
FFT(c,_lg);
for(int i=mid-1-l;i<r-l-1;i++)(f[i+l+1]+=c[i]*po(n,mod-2)%mod)%=mod;
work(mid,r);
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%lld",g+i);
for(int i=1;i<n;i++)g[i-1]=g[i]*i%mod;g[n-1]=0;
work(0,n);
for(int i=0;i<n;i++)printf("%lld%c",f[i],i==n-1?'\n':' ');
return 0;
}