ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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;
}

 

posted on 2017-07-05 18:25  nul  阅读(391)  评论(0编辑  收藏  举报