明显要找递推公式,可以通过计算出前几项再利用高斯消元来解出系数
但其实自己画一画也不难推出来,关键要细心,处理好边界
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll long long int
int const mod = 1000000007;
struct matrix
{
ll m[5][5];
};
matrix A,B,tmp;
matrix multiply(matrix x, matrix y) //矩阵乘法
{
matrix tmp;
memset(tmp.m, 0, sizeof(tmp.m));
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 4; j++)
{
if(x.m[i][j] == 0)
continue;
for(int k = 0; k < 4; k++)
{
if(y.m[j][k] == 0)
continue;
tmp.m[i][k] += x.m[i][j] * y.m[j][k];
tmp.m[i][k]=(tmp.m[i][k]%mod+mod)%mod;
}
}
}
return tmp;
}
matrix quickmod(matrix a,ll n) //矩阵快速幂
{
matrix res;
memset(res.m, 0, sizeof(res.m));
for(int i = 0; i < 4; i++)
res.m[i][i] = 1;
while(n)
{
if(n & 1)
res = multiply(res, a);
n >>= 1;
a = multiply(a, a);
}
return res;
}
int main()
{
ll n;
while(~scanf("%lld",&n))
{
if(n==1)printf("1\n");
else if(n==2)printf("5\n");
else if(n==3)printf("11\n");
else if(n==4)printf("36\n");
else
{
memset(A.m,0,sizeof(A.m));
A.m[0][0]=1;A.m[0][1]=5;A.m[0][2]=1;A.m[0][3]=-1;
A.m[1][0]=1;A.m[2][1]=1;A.m[3][2]=1;
B=quickmod(A,n-4);
ll ans=0;
ans+=36*B.m[0][0];ans=(ans%mod+mod)%mod;
ans+=11*B.m[0][1];ans=(ans%mod+mod)%mod;
ans+=5*B.m[0][2];ans=(ans%mod+mod)%mod;
ans+=1*B.m[0][3];ans=(ans%mod+mod)%mod;
printf("%lld\n",ans);
}
}
}
最后计算的时候要用线性代数中的矩阵快速幂来加速运算