1. 通常
首先能用矩阵快速幂优化的递推类型是f[n]=5f[n-3]+6f[n-2]+2f[n-1]+n^2+n+8之类的
也就是说递推是线性递推且f[n-i]前面的系数是常数,可以含有与n有关的多项式,也可以含有常数的这种递推
2.比如以下
fn=2fn−2+fn−1+n4
通常左边是f(n )及其后几项 根据具体情况定
而右边则是f(n-1) 开头的 对应左边的每一个都是n-1
但是n-1 ^4 要怎么变到n ^4 ?
这就要求我们构造了
要n-1^4 --> n ^4
这就是右边的式子 对应写出左边的式子即可
已经写出两边式子就可以求出A矩阵了。
最后给出矩阵快速幂模板
转自https://blog.csdn.net/cmershen/article/details/53265359
typedef long long ll;
ll M = 2147493647L;
class Matrix{
public:
ll mat[7][7]={
{1,2,1,4,6,4,1},
{1,0,0,0,0,0,0},
{0,0,1,4,6,4,1},
{0,0,0,1,3,3,1},
{0,0,0,0,1,2,1},
{0,0,0,0,0,1,1},
{0,0,0,0,0,0,1}
};
Matrix operator*(const Matrix& m)const{
Matrix tmp;
for(int i = 0 ; i < 7; i++){
for(int j = 0 ; j < 7 ; j++){
tmp.mat[i][j] = 0;
for(int k = 0 ; k < 7 ; k++){
tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%M;
tmp.mat[i][j] %= M;
}
}
}
return tmp;
}
};
Matrix Pow(Matrix &m , int k){
Matrix ans;
memset(ans.mat , 0 , sizeof(ans.mat));
for(int i = 0 ; i < 7 ; i++)
ans.mat[i][i] = 1;
while(k){
if(k&1)
ans = ans*m;
k >>= 1;
m = m*m;
}
return ans;
}
int T;
int main() {
int T;
ll a,b,n;
scanf("%d",&T);
while(T--) {
scanf("%I64d %I64d %I64d",&n,&a,&b);
Matrix m;
Matrix A=Pow(m,n-2);
ll ans=(A.mat[0][0]*b+A.mat[0][1]*a+A.mat[0][2]*16+A.mat[0][3]*8+A.mat[0][4]*4+A.mat[0][5]*2+A.mat[0][6]*1)%M;
cout<<ans<<endl;
}
}
及其后几项 看具体情况定