常系数其次线性递推
放个板子
#include<iostream> #include<cstdio> #define N 100002 using namespace std; typedef long long ll; const int mod=1000000007; ll a[N],h[N],num[N],ans[N],k,n,tmp[N],p[N]; inline int rd(){ int x=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c=='-')f=1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return f?-x:x; } inline void mul(ll *a,ll *b,ll *c){ for(int i=0;i<=2*k;++i)tmp[i]=0; for(int i=0;i<k;++i) for(int j=0;j<k;++j)tmp[i+j]=(tmp[i+j]+1ll*a[i]*b[j]%mod)%mod; for(int i=2*k-2;i>=k;--i){ for(int j=k-1;j>=0;--j)tmp[i-k+j]=(tmp[i-k+j]-tmp[i]*p[j]%mod+mod)%mod; tmp[i]=0; } for(int i=0;i<k;++i)c[i]=tmp[i]; } int main(){ n=rd();k=rd(); for(int i=1;i<=k;++i)a[i]=rd(); for(int i=0;i<k;++i)h[i]=rd(); p[k]=1; for(int i=1;i<=k;++i)p[k-i]=mod-a[i]; for(int i=k;i<2*k;++i){ for(int j=1;j<=k;++j)h[i]=(h[i]+h[i-j]*a[j]%mod)%mod; h[i]=(h[i]+mod)%mod; } if(n<2*k){printf("%lld",h[n]);return 0;} int b=n-k; num[1]=1;ans[0]=1; while(b){ if(b&1)mul(ans,num,ans); mul(num,num,num);b>>=1; } ll res=0; for(int i=0;i<k;++i)(res+=h[i+k]*ans[i]%mod)%=mod;; cout<<res; return 0; }