[ 齐次线性递推式 ] BZOJ4161 Shlw loves matrixI

假设转移矩阵为 A A
然后就是要求出 hAnk+1 h A n − k + 1
A A 的特征多项式为 f(A)=Akki=1aiAki=0 f ( A ) = A k − ∑ i = 1 k a i A k − i = 0
所以 xnk+1xnk+1 ( mod f(A) ) x n − k + 1 ≡ x n − k + 1   (   m o d   f ( A )   ) ,假设其为 k1i=0cixi ∑ i = 0 k − 1 c i x i
我们要求的答案是 hAnk+1 h A n − k + 1 的第一行元素,即为 k1i=0cihAi ∑ i = 0 k − 1 c i h A i
由于 A A 是转移矩阵, hAi=hi+k1 h A i = h i + k − 1 ,然后乘起来就好了。

#include
using namespace std;
const int N=4010;
const int P=1000000007;
int n,m,k,Ans;
int mod[N];
int a[N],b[N],c[N],h[N];
int t[N];
void Add(int& x,int y) {
    x=(x+y)%P;
}
void Mul(int* a,int* b,int* c) {
    memset(t,0,sizeof(t));
    for(int i=0;i<=k;i++)
        for(int j=0;j<=k;j++)
            Add(t[i+j],1ll*a[i]*b[j]%P);
    for(int i=(k<<1);i>=k;i--) 
        for(int j=0;j1ll*mod[j]*t[i]%P);
    for(int i=0;iint main() {
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++) scanf("%d",&a[i]);
    for(int i=0;i"%d",&h[i]);
    for(int i=0;i1;
    c[0]=b[1]=1;
    for(n-=k-1;n;n>>=1) {
        if(n&1) Mul(b,c,c);
        Mul(b,b,b);
    }
    for(int i=k;i<(k<<1);i++)
        for(int j=1;j<=k;j++)
            Add(h[i],1ll*a[j]*h[i-j]%P);
    for(int i=0;i1ll*c[i]*h[i+k-1]%P);
    cout<<(Ans+P)%P<return 0;
}

你可能感兴趣的:(齐次线性递推式)