常系数齐次线性递推板子
板子是抄的
不过他m=1的情况有bug要特判
#include <bits/stdc++.h> using namespace std; #define rep(i,h,t) for (int i=h;i<=t;i++) #define dep(i,t,h) for (int i=t;i>=h;i--) #define me(x) memset(x,0,sizeof(x)) #define IL inline #define rint register int #define ll long long using namespace std; const int N=150150,P=998244353; // len=32000--->n=150150 struct F{ #define FF for (int i=0;i<L;i++) #define CON(a,b) DFT(a,L);FF a[i]=1ll*a[i]*b[i]%P;IFT(a,L); int n,m,K,L,o,A,Q; int rv[N],W[N],p[N],f[N],t[N],a[N],b[N],C[N]; unsigned long long B[N]; int qpw(int x,int y){int z=1;for(;y;y>>=1,x=1ll*x*x%P)if(y&1) z=1ll*z*x%P;return z;} void ini(int n){ for(L=1;L<=n;L<<=1,o++); FF rv[i]=rv[i>>1]>>1|(i&1)<<(o-1); int V=qpw(3,P>>o);W[L>>1]=1; rep(i,(L>>1)+1,L-1) W[i]=1ll*W[i-1]*V%P; dep(i,(L>>1)-1,1) W[i]=W[i<<1]; } void DFT(int*A,int L){ int u=o-__builtin_ctz(L),t; FF B[i]=A[rv[i]>>u]; for(int i=1;i<L;i<<=1)for(int j=0,s=i<<1;j<L;j+=s) rep(k,0,i-1) t=B[i+j+k]*W[i+k]%P,B[i+j+k]=B[j+k]+P-t,B[j+k]+=t; FF A[i]=B[i]%P; } void IFT(int*A,int L){ reverse(A+1,A+L);DFT(A,L); int V=P-(P-1)/L; FF A[i]=1ll*A[i]*V%P; } int upl(int n){return 1<<(32-__builtin_clz(n));} void INV(int*A,int*B,int n){ static int L; if(!n) return B[0]=qpw(A[0],P-2),void(); INV(A,B,n>>1);L=upl(n<<1); FF C[i]=i>n?0:A[i]; DFT(C,L);DFT(B,L); FF B[i]=(2-1ll*C[i]*B[i]%P+P)*B[i]%P;IFT(B,L); FF B[i]=i>n?0:B[i],C[i]=0; } void MUL(int*A,int*B){ FF C[i]=A[i];DFT(C,L); CON(B,C); FF C[i]=i>K?0:B[n-i]; CON(C,t); FF C[i]=i>K?0:C[i]; reverse(C,C+K+1); CON(C,p); FF (B[i]+=P-C[i])%=P; } // f[i]=p[j]*f[i-j](1<=j<=m) f[0..n-1] Q:f[Q] void solve(){ cin>>Q>>m; ini(m<<1);n=m-1<<1;K=n-m; rep(i,1,m) { cin>>p[i]; p[i]=(p[i]%P+P)%P;} rep(i,0,m-1) { cin>>f[i]; f[i]=(f[i]%P+P)%P;} //if (m=1) special judge if (m==1) { cout<<((f[0]*qpw(p[1],Q)%P)+P)%P<<endl; return 0; } p[0]=P-1; INV(p,t,K);DFT(t,L); reverse(p,p+m+1);DFT(p,L); a[1]=b[0]=1; for(;Q;Q>>=1,MUL(a,a))if(Q&1) MUL(a,b); rep(i,0,m-1) (A+=1ll*b[i]*f[i]%P)%=P; cout<<A<<'\n'; } } F; int main() { ios::sync_with_stdio(false); F.solve(); return 0; }