关于exp 多项式长度
查看原帖
关于exp 多项式长度
98490
houzhiyuan楼主2022/4/24 14:43

为什么长度是 nn 做会WA20,如果长度是 2×n2\times n 就过了啊。

递归写法,lnln 是贺模板的。

#include<bits/stdc++.h>
using namespace std;
const int N=8e5+5,mod=998244353,G=3;
int kuai(int a,int b){
    int ans=1;
    for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;
    return ans;
}
int S,cnt[N],Gi;
void NTT(int *A,int T){
    for(int i=0;i<=S;i++)if(i<cnt[i])swap(A[i],A[cnt[i]]);
    for(int len=1;len<S;len<<=1){
        int W=kuai(T?G:Gi,(mod-1)/(len*2));
        for(int L=0;L<S;L+=len*2){
            int now=1;
            for(int k=0;k<len;k++,now=1ll*now*W%mod){
                int x=A[L+k],y=1ll*A[L+len+k]*now%mod;
                A[L+k]=(x+y)%mod,A[L+len+k]=(x-y+mod)%mod;
            }
        }
    }
}
int l,A[N],B[N];
void mul(int *a,int *b,int *ans,int n,int m,int p){
    for(S=1,l=0;S<=n+m;S<<=1,l++);
    for(int i=0;i<=S;i++)A[i]=B[i]=0;
    for(int i=0;i<=n;i++)A[i]=a[i];
    for(int i=0;i<=m;i++)B[i]=b[i];
    for(int i=1;i<=S;i++)cnt[i]=(cnt[i>>1]>>1)+((i&1)<<(l-1));
    NTT(A,1),NTT(B,1);
    for(int i=0;i<=S;i++)A[i]=1ll*A[i]*B[i]%mod;
    NTT(A,0);
    int Inv=kuai(S,mod-2);
    for(int i=0;i<p;i++)ans[i]=1ll*A[i]*Inv%mod;
}
void Dao(int *a,int *ans,int n){
    for(int i=0;i<=n;i++)A[i]=a[i],ans[i]=0;
    for(int i=0;i<n;i++)ans[i]=1ll*A[i+1]*(i+1)%mod;
}
void Ji(int *a,int *ans,int n){
    for(int i=0;i<=n;i++)A[i]=a[i],ans[i]=0;
    for(int i=1;i<=n;i++)ans[i]=1ll*A[i-1]*kuai(i,mod-2)%mod;
}
int h[N];
void get_Inv(int *a,int *f,int n){
    if(n==1){f[0]=1;return;}
    int mid=(n+1)/2;
    get_Inv(a,f,mid);
    mul(f,f,h,mid,mid,n),mul(h,a,h,n,n,n);
    for(int i=0;i<n;i++)f[i]=(2ll*f[i]%mod-h[i]+mod)%mod;
}
int g[N],f[N];
void get_Ln(int *a,int *ans,int n){get_Inv(a,f,n),Dao(a,g,n),mul(g,f,g,n,n,n),Ji(g,ans,n);}
int F[N];
void get_Exp(int *a,int *ans,int n){
	if(n==1){ans[0]=1;return;}
	get_Exp(a,ans,(n+1)/2);
	get_Ln(ans,F,n);
	for(int i=0;i<n;i++)F[i]=(a[i]-F[i]+mod)%mod;
	F[0]++;
	mul(ans,F,ans,n,n,n);
}
int n,a[N],ans[N];
int main(){
    Gi=kuai(G,mod-2);
    scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    get_Exp(a,ans,2*n);//此处写2*n AC,写n WA
    for(int i=0;i<n;i++)printf("%d ",ans[i]);
}
2022/4/24 14:43
加载中...