列出方程组:
a1*f(n-1)+a2*f(n-2)+a3*f(n-3)+...+ad*f(n-d)=f(n)
f(n-1) =f(n-1)
f(n-2) =f(n-2)
f(n-3) =f(n-3)
f(n-d)=f(n-d)
解线性方程组, 转化成矩阵形式:
A × F(n-1) = F(n)
a1 | a2 | a3 | ... | ad |
1 | ||||
1 | ||||
1 | ||||
... | 1 |
f(n-1) |
f(n-2) |
f(n-3) |
... |
f(n-d) |
f(n) |
f(n-1) |
f(n-2) |
... |
f(n-d) |
递推:
A × F(n-1) = F(n)
A × F(n-2) = F(n-1)
A × F(n-3) = F(n-2)
...
得出:
An-d × F(d) = F(n)
其中F(d)为:
f(d) |
f(d-1) |
f(d-2) |
... |
f(1) |
剩下就是求矩阵A的n-d次幂,以及求矩阵与向量的乘,F(n)中的f(n)为所求~
void matrix_mul(Matrix A, Matrix B, Matrix res) { Matrix C; memset(C, 0, sizeof(C)); for(int i = 0; i < sz; ++i) for(int j = 0; j < sz; ++j) for(int k = 0; k < sz; ++k ) C[i][j] = (C[i][j] + A[i][k]*B[k][j]) % mod; memcpy(res, C, sizeof(C)); } void matrix_pow(Matrix A, int n, Matrix res) { Matrix a, r; memcpy(a, A, sizeof(a)); memset(r, 0, sizeof(r)); for(int i = 0; i < sz; ++i) r[i][i] = 1; while(n) { if(n&1) matrix_mul(r, a, r); n >>= 1; matrix_mul(a, a, a); } memcpy(res, r, sizeof(r)); }
注意一下这个:
typedef i64 Matrix[maxn][maxn];
typedef i64 Vector[maxn];