Description
给定数列 {hn}前k项,其后每一项满足
hn = a1*h(n-1) + a2*h(n-2) + ... + ak*h(n-k)
其中 a1,a2...ak 为给定数列。请计算 h(n),并将结果对 1000000007 取模输出。
Input
第 1 行包含两个整数 n,k
第 2 行包含 k 个整数 a1,a2...ak
第 3 行包含 k 个整数 h1,h2...hk
Output
一行一个整数 hn mod 1000000007
常系数线性齐次递推可转为多项式幂取模
#include<cstdio> #define F(i,l,r) for(int i=l;i<r;++i) #define Fe(i,l,r) for(int i=l;i<=r;++i) typedef long long i64; const int P=1000000007; const int MX=7e18/(1ll<<32),MN=-MX; inline i64 fix(i64 x){return (int(x>>32)>MX||int(x>>32)<MN)?x%P:x;} int n,k,a[2007],f[2007],x[2007],y[2007]; i64 _t[4007],ans=0; void pol_mul(int*a,int*b){ Fe(i,0,k*2-2)_t[i]=0; F(i,0,k)F(j,0,k)_t[i+j]=fix(_t[i+j]+i64(a[i])*b[j]); for(int i=k*2-2;i>=k;--i){ i64 c=_t[i]%P; Fe(j,1,k)_t[i-j]=fix(_t[i-j]+c*f[j]); } F(i,0,k)a[i]=_t[i]%P; } int main(){ scanf("%d%d",&n,&k); Fe(i,1,k)scanf("%d",f+i); Fe(i,1,k)scanf("%d",a+i); x[0]=1; if(k>1)y[1]=1; else y[0]=f[1]; for(;n;n>>=1,pol_mul(y,y))if(n&1)pol_mul(x,y); for(int i=0;i<k;++i)ans=fix(ans+x[i]*i64(a[i+1])); printf("%lld\n",(ans%P+P)%P); return 0; }