Yiwen with Formula
溢流眼泪题解
生成函数化成n个多项式乘积,然后分治把他们依次相乘,需要由于指数需要modϕ(998244353)=998244353−1\bmod \phi(998244353)=998244353-1modϕ(998244353)=998244353−1,因此需要任意模数的FFT。。。
常数贼大跑不过去
#include<bits/stdc++.h>using namespace std;
using ll=long long;const int N=400010;
const long double PI=acos(-1);
const int mod=998244353;
struct Complex
{long double r,i;Complex operator+(const Complex &o) const{return{r+o.r,i+o.i};} Complex operator-(const Complex &o) const{return{r-o.r,i-o.i};} Complex operator*(const Complex &o) const{return{r*o.r-i*o.i,r*o.i+i*o.r};} Complex operator*(const long double &o) const{return{r*o,i*o};}Complex conj(){return {this->r,-this->i};}
}a0[N],a1[N],b0[N],b1[N];
const Complex I={0,1};
int n,m;
int rev[N];
void FFT(Complex *a,int n,int inv)
{for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);for(int mid=1;mid<n;mid<<=1){Complex Wn=Complex({cos(PI/mid),inv*sin(PI/mid)});for(int i=0;i<n;i+=mid*2){Complex w=Complex({1,0});for(int j=0;j<mid;j++,w=w*Wn){Complex x=a[i+j],y=w*a[i+j+mid];a[i+j]=x+y,a[i+j+mid]=x-y;}}}if(inv==-1) for(int i=0;i<N;i++) a[i].r/=n,a[i].i/=n;
}
void DFFT(Complex *a,Complex *b,int n)
{for(int i=0;i<n;i++) a[i]=a[i]+I*b[i];FFT(a,n,1);for(int i=0;i<n;i++) b[i]=a[i?n-i:0].conj();for(int i=0;i<n;i++){Complex p=a[i],q=b[i];a[i]=(p+q)*0.5;b[i]=(q-p)*0.5*I;}
}
Complex p[N],q[N];ll f(long double x,int mod) {return (x<0)?((ll(x-0.5)+mod)%mod):(ll(x+0.5)%mod);}
int MTT(int *a,int *b,int n,int m,int *ans,int mod)
{const int M=sqrt(mod)+1;int bit=0,num;while((1<<bit)<n+m+1) bit++;num=1<<bit;for(int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));for(int i=0;i<num;i++) a0[i]=a1[i]=b0[i]=b1[i]={0,0};for(int i=0;i<=n;i++) a0[i].r=a[i]/M,a1[i].r=a[i]%M;for(int i=0;i<=m;i++) b0[i].r=b[i]/M,b1[i].r=b[i]%M;DFFT(a0,a1,num);DFFT(b0,b1,num);for(int i=0;i<num;i++){p[i]=a0[i]*b0[i]+I*a1[i]*b0[i];q[i]=a0[i]*b1[i]+I*a1[i]*b1[i];}FFT(p,num,-1);FFT(q,num,-1);for(int i=0;i<=n+m;i++){ll a=f(p[i].r,mod);ll b=f(p[i].i,mod);ll c=f(q[i].r,mod);ll d=f(q[i].i,mod);ans[i]=(int)((1ll*M*M*a%mod+1ll*M*(b+c)%mod+d)%mod);}return n+m;
}
//=======================================================================
ll qmi(ll a,ll b)
{ll v=1;while(b){if(b&1) v=v*a%mod;b>>=1;a=a*a%mod;}return v;
}
int pool[N],tot;
struct Node
{int *p,n;void init(int n){this->n=n;p=pool+tot;for(int i=0;i<=n;i++) p[i]=0;p[0]++;p[n]++;tot+=n+1;}void mul(const Node&o){n=MTT(p,o.p,n,o.n,p,mod-1);}
};
Node solve(int l,int r)
{Node ans;if(l==r){int x;cin>>x;ans.init(x);return ans;}int mid=l+r>>1;ans=solve(l,mid);ans.mul(solve(mid+1,r));return ans;
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int Tc;cin>>Tc;while(Tc--){tot=0;int n;cin>>n;Node res=solve(1,n);if(res.p[0]>1) cout<<"0\n";else{ll ans=1;for(int i=1;i<=res.n;i++) ans=ans*qmi(i,res.p[i])%mod;cout<<ans<<'\n';}}return 0;
}