题意:
给一递推公式:
求S(n)
因为A(n) = X*A(n-1)+Y*A(n-2),
所以,A(n) ^2= X^2*A(n-1)^2+Y^2*A(n-2)+2*X*Y*A(n-1)*A(n-2)
又有:S(n) =S(n-1)+A(n)^2 = S(n-1)+X^2*A(n-1)^2+Y^2*A(n-2)+2*X*Y*A(n-1)*A(n-2)
构造矩阵如下:
| S(n) | | 1 X^2 Y^2 2XY | | S(n-1) |
| A(n)^2 | = | 0 x^2 Y^2 2XY | | A(n-1)^2 |
| A(n-1)^2 | | 0 1 0 0 | | A(n-2)^2 |
| A(n)A(n-1) | | 0 X 0 Y | | A(n-1)A(n-2) |
构造矩阵的过程注意递推式的使用。写代码 矩阵初始化时注意取模,防止溢出。
代码:
#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])%10007;
res.matrix[i][j] = sum%10007;
}
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 N,X,Y;
Matrix res;
while(scanf("%d%d%d",&N,&X,&Y)!=EOF)
{
if(N==0||N==1)
{
printf("%d\n",N+1);
continue;
}
X%=10007,Y%=10007;
res.matrix[0][0] = 1;
res.matrix[0][1] = (X*X)%10007;
res.matrix[0][2] = (Y*Y)%10007;
res.matrix[0][3] = (2*X*Y)%10007;
res.matrix[1][0] = 0;
res.matrix[1][1] = (X*X)%10007;
res.matrix[1][2] = (Y*Y)%10007;
res.matrix[1][3] = (2*X*Y)%10007;
res.matrix[2][0] = 0;
res.matrix[2][1] = 1;
res.matrix[2][2] = 0;
res.matrix[2][3] = 0;
res.matrix[3][0] = 0;
res.matrix[3][1] = X%10007;
res.matrix[3][2] = 0;
res.matrix[3][3] = Y%10007;
res = powermod(res,N-1);
printf("%d\n",(2*res.matrix[0][0]+res.matrix[0][1]+res.matrix[0][2]+res.matrix[0][3])%10007);
}
return 0;
}