[ 齊次線性遞推式 ] BZOJ4161 Shlw loves matrixI

假設轉移矩陣爲 A
然後就是要求出 hAnk+1
A 的特徵多項式爲 f(A)=Aki=1kaiAki=0
所以 xnk+1xnk+1 ( mod f(A) ) ,假設其爲 i=0k1cixi
我們要求的答案是 hAnk+1 的第一行元素,即爲 i=0k1cihAi
由於 A 是轉移矩陣, hAi=hi+k1 ,然後乘起來就好了。

#include<bits/stdc++.h>
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;j<k;j++)
            Add(t[i-k+j],-1ll*mod[j]*t[i]%P);
    for(int i=0;i<k;i++) c[i]=t[i];
}
int main() {
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++) scanf("%d",&a[i]);
    for(int i=0;i<k;i++) scanf("%d",&h[i]);
    for(int i=0;i<k;i++) mod[i]=-a[k-i];mod[k]=1;
    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;i<k;i++)
        Add(Ans,1ll*c[i]*h[i+k-1]%P);
    cout<<(Ans+P)%P<<endl;
    return 0;
}
發佈了288 篇原創文章 · 獲贊 104 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章