BZOJ4161 常系数齐次线性递推

问了数竞的毛毛搞了一番也没太明白,好在代码蛮好写先记下吧。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=4005,mod=1e9+7;
 4 int n,k,c[N],b[N],a[N],f[N],tmp[N],ans;
 5 inline void qmul(int *x,int *y)
 6 {
 7     for(int i=0;i<k*2;++i)tmp[i]=0;
 8     for(int i=0;i<k;++i)
 9     for(int j=0;j<k;++j)
10     tmp[i+j]=(tmp[i+j]+1ll*x[i]*y[j]%mod)%mod;
11     for(int i=k*2-2;i>=k;--i)
12     for(int j=1;j<=k;++j)
13     tmp[i-j]=(tmp[i-j]+1ll*tmp[i]*a[j]%mod)%mod;
14     for(int i=0;i<k;++i)x[i]=tmp[i];
15     return;
16 }
17 int main()
18 {
19     scanf("%d%d",&n,&k);
20     for(int i=1;i<=k;++i)scanf("%d",&a[i]),a[i]=(a[i]%mod+mod)%mod;
21     for(int i=0;i<k;++i)scanf("%d",&f[i]),f[i]=(f[i]%mod+mod)%mod;
22     c[1]=b[0]=1;
23     if(n<k){
24         printf("%d\n",f[n]);
25         return 0;
26     }
27     while(n)
28     {
29         if(n&1)qmul(b,c);
30         qmul(c,c);n>>=1;
31     }
32     for(int i=0;i<k;++i)ans=(ans+1ll*f[i]*b[i]%mod)%mod;
33     printf("%d\n",ans);
34     return 0;
35 }

 

posted @ 2018-03-21 17:25  大奕哥&VANE  阅读(423)  评论(0编辑  收藏  举报