[用途]
n较大时,求简单递推式 F n = ∑ i = 1 n − 1 k i F n − i + s o m e t h i n g , ( k i ∈ Z ) F_n=\sum\limits_{i=1}^{n-1}{k_iF_{n-i}}+something,(k_i\in Z) Fn=i=1∑n−1kiFn−i+something,(ki∈Z)
[构造形式]
构建矩阵X,A,B,使矩阵X乘以矩阵A等于矩阵B , (注意一般情况下矩阵不满足交换律!!!)
[构造方法]
- 含 F n − i F_{n-i} Fn−i的项依次按照顺序填入矩阵A中
- s o m e t h i n g something something中常数项与 ( n − 1 ) k (n-1)^k (n−1)k项也依次填入矩阵A中
-
s
o
m
e
t
h
i
n
g
something
something含
n
k
n^k
nk的项根据二项式定理
( 1 + x ) n = ∑ i = 0 n C n i x n (1+x)^{n}=\sum\limits_{i=0}^n{C_{n}^{i}x^{n}} (1+x)n=i=0∑nCnixn
则 n k = ( 1 + ( n − 1 ) ) k = ∑ i = 0 k C k i ( n − 1 ) i n^k=(1+(n-1))^k=\sum\limits_{i=0}^k{C_{k}^{i}(n-1)^{i}} nk=(1+(n−1))k=i=0∑kCki(n−1)i
这样就转化为了含 ( n − 1 ) k (n-1)^k (n−1)k的项
构 建 后 的 矩 阵 A 类 似 于 : [ F n − 1 0 0 . . . 0 F n − 2 0 0 . . . 0 . . . 0 0 . . . 0 ( n − 1 ) k 0 0 . . . 0 ( n − 1 ) k − 1 0 0 . . . 0 . . . 0 0 . . . 0 ( n − 1 ) 0 0 0 . . . 0 ] 构建后的矩阵A类似于:\left[ \begin{matrix} F_{n-1} &0&0&...&0\\ F_{n-2} &0&0&...&0\\ \quad ...&0&0&...&0\\ (n-1)^k &0&0&...&0\\ (n-1)^{k-1} &0&0&...&0\\ \quad ...&0&0&...&0\\ (n-1)^0 &0&0&...&0\\ \end{matrix} \right] 构建后的矩阵A类似于:⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡Fn−1Fn−2...(n−1)k(n−1)k−1...(n−1)000000000000000.....................0000000⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
构
建
后
的
矩
阵
B
类
似
于
:
[
F
n
0
0
.
.
.
0
F
n
−
1
0
0
.
.
.
0
.
.
.
0
0
.
.
.
0
n
k
0
0
.
.
.
0
n
k
−
1
0
0
.
.
.
0
.
.
.
0
0
.
.
.
0
n
0
0
0
.
.
.
0
]
构建后的矩阵B类似于:\left[ \begin{matrix} F_{n} &0&0&...&0\\ F_{n-1} &0&0&...&0\\ \quad ...&0&0&...&0\\ n^k &0&0&...&0\\ n^{k-1} &0&0&...&0\\ \quad ...&0&0&...&0\\ n^0 &0&0&...&0\\ \end{matrix} \right]
构建后的矩阵B类似于:⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡FnFn−1...nknk−1...n000000000000000.....................0000000⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
然后根据矩阵乘法求X
B
[
i
]
[
j
]
为
矩
阵
X
的
第
i
行
与
矩
阵
A
的
第
j
列
对
应
相
乘
所
得
的
和
,
由
已
知
递
推
式
求
系
数
即
可
B[i][j]为矩阵X的第i行与矩阵A的第j列对应相乘所得的和,由已知递推式求系数即可
B[i][j]为矩阵X的第i行与矩阵A的第j列对应相乘所得的和,由已知递推式求系数即可
[代码]
F
n
=
2
F
n
−
2
+
F
n
−
1
+
n
3
F_n=2F_{n-2}+F_{n-1}+n^3
Fn=2Fn−2+Fn−1+n3
根据上述有
A
=
[
F
n
−
1
0
0
0
0
0
F
n
−
2
0
0
0
0
0
(
n
−
1
)
3
0
0
0
0
0
(
n
−
1
)
2
0
0
0
0
0
(
n
−
1
)
1
0
0
0
0
0
1
0
0
0
0
0
]
A=\left[ \begin{matrix} F_{n-1} &0&0&0&0&0\\ F_{n-2} &0&0&0&0&0\\ (n-1)^3 &0&0&0&0&0\\ (n-1)^2 &0&0&0&0&0\\ (n-1)^{1} &0&0&0&0&0\\ 1 &0&0&0&0&0 \end{matrix} \right]
A=⎣⎢⎢⎢⎢⎢⎢⎡Fn−1Fn−2(n−1)3(n−1)2(n−1)11000000000000000000000000000000⎦⎥⎥⎥⎥⎥⎥⎤ ,
B
=
[
F
n
0
0
0
0
0
F
n
−
1
0
0
0
0
0
n
3
0
0
0
0
0
n
2
0
0
0
0
0
n
1
0
0
0
0
0
1
0
0
0
0
0
]
B=\left[ \begin{matrix} F_{n} &0&0&0&0&0\\ F_{n-1} &0&0&0&0&0\\ n^3 &0&0&0&0&0\\ n^2 &0&0&0&0&0\\ n^{1} &0&0&0&0&0\\ 1 &0&0&0&0&0 \end{matrix} \right]
B=⎣⎢⎢⎢⎢⎢⎢⎡FnFn−1n3n2n11000000000000000000000000000000⎦⎥⎥⎥⎥⎥⎥⎤
则 X = [ 1 2 1 3 3 1 1 0 0 0 0 0 0 0 1 3 3 1 0 0 0 1 2 1 0 0 0 0 1 1 0 0 0 0 0 1 ] X=\left[ \begin{matrix} 1&2&1&3&3&1\\ 1&0&0&0&0&0\\ 0 &0&1&3&3&1\\ 0 &0&0&1&2&1\\ 0 &0&0&0&1&1\\ 0 &0&0&0&0&1 \end{matrix} \right] X=⎣⎢⎢⎢⎢⎢⎢⎡110000200000101000303100303210101111⎦⎥⎥⎥⎥⎥⎥⎤
设基准点是F[2],矩阵 A = [ 2 ( 即 F [ 2 ] ) 0 0 0 0 0 1 即 ( F [ 1 ] ) 0 0 0 0 0 8 0 0 0 0 0 4 0 0 0 0 0 2 0 0 0 0 0 1 0 0 0 0 0 ] A=\left[ \begin{matrix} 2(即F[2]) &0&0&0&0&0\\ 1 即(F[1])&0&0&0&0&0\\ 8 &0&0&0&0&0\\ 4 &0&0&0&0&0\\ 2 &0&0&0&0&0\\ 1 &0&0&0&0&0 \end{matrix} \right] A=⎣⎢⎢⎢⎢⎢⎢⎡2(即F[2])1即(F[1])8421000000000000000000000000000000⎦⎥⎥⎥⎥⎥⎥⎤
求F[n],矩阵 B = X n − 2 ∗ A B=X^{n-2}*A B=Xn−2∗A,即F[n]=B[0][0]
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const LL N=6;
const LL mod=123456789;
struct jz{
LL A[N][N];
inline jz friend operator*(jz x,jz y){
jz ans;
memset(ans.A,0,sizeof(ans.A));
for(LL i=0;i<N;++i)
for(LL j=0;j<N;++j)
for(LL k=0;k<N;++k)
ans.A[i][j]=(ans.A[i][j]+x.A[i][k]*y.A[k][j])%mod;
return ans;
}
};
jz jzksm(jz x,LL n)
{
jz ans;
memset(ans.A,0,sizeof(ans.A));
for(LL i=0;i<N;++i)ans.A[i][i]=1;
while(n){
if(n&1)ans=ans*x;
n>>=1;
x=x*x;
}
return ans;
}
int main()
{
jz first={
2,0,0,0,0,0,
1,0,0,0,0,0,
8,0,0,0,0,0,
4,0,0,0,0,0,
2,0,0,0,0,0,
1,0,0,0,0,0,
};
jz x={
1,2,1,3,3,1,
1,0,0,0,0,0,
0,0,1,3,3,1,
0,0,0,1,2,1,
0,0,0,0,1,1,
0,0,0,0,0,1,
};
LL n,T;
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
jz ans=jzksm(x,n-2)*first;
printf("%lld\n",ans.A[0][0]);
}
return 0;
}