结论是,若
∑
i
=
0
k
a
i
h
n
−
i
=
0
\sum_{i=0}^{k}a_ih_{n-i}=0
∑i=0kaihn−i=0,那么
h
n
=
∑
i
=
0
k
−
1
b
i
h
i
h_n=\sum_{i=0}^{k-1} b_i h_i
hn=∑i=0k−1bihi,其中
b
b
b为
x
n
x^n
xn对
A
T
(
x
)
A^T(x)
AT(x)取模后的结果。
实在不想写多项式取模了……
所以写了个k<=2000的版本。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define mod 1000000007
#define lint long long
#define K 4010
#define LOG 40
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
int b[LOG][K],a[K],h[K];
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
inline int mol(lint x) { return x%=mod,(x<0?x+mod:x); }
inline int fast_pow(int x,int k,int ans=1)
{ for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
inline int show(int *a,int n)
{
for(int i=0;i<=n;i++) cerr<<a[i]<<" ";cerr<<endl;
return 0;
}
inline int tms(int *a,int *b,int *c,int n)
{
memset(c,0,sizeof(int)*(n*2+1));
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
(c[i+j]+=(lint)a[i]*b[j]%mod)%=mod;
return 0;
}
inline int mol(int *a,int n,int *b,int m)
{
for(int i=n;i>=m;i--)
{
int v=(lint)a[i]*fast_pow(b[m],mod-2)%mod;
for(int j=m;j>=0;j--) a[i+j-m]=mol(a[i+j-m]-(lint)v*b[j]);
}
return 0;
}
inline int solve(int n,int *a,int m,int d)
{
if(n<m) return memset(b[d],0,sizeof(int)*m),b[d][n]=1;
solve(n/2,a,m,d+1),tms(b[d+1],b[d+1],b[d],m-1);
if(n&1) for(int i=m*2-1;i>=1;i--) b[d][i]=b[d][i-1];
if(n&1) b[d][0]=0;return mol(b[d],m*2-2+(n&1),a,m);
}
int main()
{
int n=inn(),k=inn();a[0]=1;
for(int i=1;i<=k;i++) scanf("%d",&a[i]),a[i]=mol(-a[i]);
for(int i=0;i<k;i++) scanf("%d",&h[i]),h[i]=mol(h[i]);
if(n<k) return !printf("%d\n",h[n]);
for(int i=0;i<=k/2;i++) swap(a[i],a[k-i]);
solve(n,a,k,0);int ans=0;
for(int i=0;i<k;i++) (ans+=(lint)h[i]*b[0][i]%mod)%=mod;
return !printf("%d\n",ans);
}