题意:给出F(n)的线性递推关系:F(n) = 3F(n-1)+2F(n-2)+7F(n-3),求S(n) = F(0)+F(1)+F(2)+...+F(n).
解题思路: 由F(n)的线性常系数递推关系可知,F(n)可由矩阵乘法求出。再在求S(n)时二分求解,可得答案。但这样做TLE。
于是,我们可以增加一维,构造S(n)的递推关系:S(n)=S(n-1)+F(n) = S(n-1)+3F(n-1)+2F(n-2)+7F(n-3)
于是我们可以构造矩阵如下:
之后,便可利用矩阵快速幂求解。
代码:
#include <stdio.h>
typedef struct
{
int matrix[4][4];
}Matrix;
Matrix multi(Matrix x,Matrix y)
{
Matrix res;
int i,j,k;
int sum;
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
{
sum = 0;
for(k = 0;k<4;k++)
sum+=x.matrix[i][k]*y.matrix[k][j];
res.matrix[i][j] = sum%2009;
}
return res;
}
Matrix powermod(Matrix x,int n)
{
Matrix res;
int i,j;
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
{
if(i==j)
res.matrix[i][j] = 1;
else
res.matrix[i][j] = 0;
}
for(;n;n>>=1)
{
if(n&1)
res = multi(res,x);
x = multi(x,x);
}
return res;
}
int main()
{
int T,c = 0,i,j,n,sum;
int num[4] = {1,3,5,9};
Matrix x;
scanf("%d",&T);
while(T--)
{
c++;
scanf("%d",&n);
if(n<3)
{
sum = 0;
for(i = 0;i<=n;i++)
sum+=num[i];
printf("Case %d: %d\n",c,sum);
}
else
{
x.matrix[0][0] = 1;
x.matrix[0][1] = 3;
x.matrix[0][2] = 2;
x.matrix[0][3] = 7;
x.matrix[1][0] = 0;
x.matrix[1][1] = 3;
x.matrix[1][2] = 2;
x.matrix[1][3] = 7;
for(i = 2;i<4;i++)
for(j = 0;j<4;j++)
{
if(i-j==1)
x.matrix[i][j] = 1;
else
x.matrix[i][j] = 0;
}
x = powermod(x,n-2);
sum = 0;
for(i = 0;i<4;i++)
sum+=x.matrix[0][i]*num[3-i];
printf("Case %d: %d\n",c,sum%2009);
}
}
return 0;
}