bzoj #4161. Shlw loves matrixI 常系数线性递推
做法:容易得到一个\(k^3logn\)的做法,考虑更快。
需要利用矩阵特征方程f(x) (恰好前些天刚学
对\(A^n\) 用\(f(A)\)可以对其取模。之后就可以快速求出了。
我学的不深很难进行证明 但是可以理解。需要多项式取余 暴力的话复杂度\(k^2logn\)
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 2000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define l(x) s[x].l
#define r(x) s[x].r
#define S second
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define add(x,y) (x+y>=mod?x+y-mod:x+y)
using namespace std;
const int MAXN=2010;
int n,k;
int a[MAXN],b[MAXN];
int f[MAXN<<1],g[MAXN<<1],tmp[MAXN<<1];
inline void gx(int &x)
{
x=(x%mod+mod)%mod;
return;
}
inline void mul(int *f,int *g)
{
rep(0,k-1,i)rep(0,k-1,j)
{
tmp[i+j]+=(ll)f[i]*g[j]%mod;
gx(tmp[i+j]);
}
for(int i=2*k-2;i>=k;--i)
{
int ww=tmp[i];
for(int j=k;j>=0;--j)
{
tmp[i-k+j]-=(ll)ww*a[j]%mod;
gx(tmp[i-k+j]);
}
}
rep(0,k-1,i)f[i]=tmp[i],tmp[i]=0;
}
inline void solve(int p)
{
while(p)
{
if(p&1)mul(f,g);
mul(g,g);p=p>>1;
}
}
int main()
{
freopen("1.in","r",stdin);
sc(n);sc(k);
rep(0,k-1,i)
{
sc(a[i]);
a[i]=-a[i];
}
reverse(a,a+k);
gx(a[0]);
rep(1,k,i)
{
sc(b[i]);
gx(a[i]);gx(b[i]);
}
a[k]=1;
if(n<k){put(b[n+1]);return 0;}
f[0]=1;g[1]=1;
solve(n);
int ans=0;
rep(0,k-1,i)
{
ans+=(ll)f[i]*b[i+1]%mod;
gx(ans);
}
put(ans);
return 0;
}