复习下矩阵!!哎,都忘光了。
题意:输入x,y,n的值,给定公式f[0]=f[1]=1;f[n]=x*f[n-1]+y*f[n-2](n>=2);求s[n]=f[0]^2+f[1]^2+...+f[n]^2;的值。
题解:矩阵的题就是想方法构造矩阵。这题出现f[n]^2,所以要推导下。f[n]^2=(x*f[n-1]+y*f[n-2])^2=x^2*f[n-1]^2+y^2*f[n-2]^2+2*x*y*f[n-1]*f[n-2];由于其中的f[n-1]*f[n-2]不能直接从f[n-1]和f[n-2]矩阵连乘得到,所以还需要推f[n]*f[n-1]=(x*f[n-1]+y*f[n-2])*f[n-1]=x*f[n-1]^2+y*f[n-1]*f[n-2];
以此我们可以得到矩阵矩阵:
|f[n-1]^2 f[n-2]^2 f[n-1]*f[n-2] s[n-2]|*
|x^2 1 x 1|
|y^2 0 0 0|
|2xy 0 y 0|
|0 0 0 1|
=|f[n]^2 f[n-1]^2 f[n]*f[n-1] s[n-1]|
好坑的排版
代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define LL __int64
const int mod=10007;
struct matrix{
LL f[4][4];
};
matrix mul(matrix a,matrix b)//矩阵乘法
{
int i,j,k;
matrix c;
memset(c.f,0,sizeof(c.f));
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
for(k=0;k<4;k++)
{
c.f[i][j]+=a.f[i][k]*b.f[k][j];
c.f[i][j]%=mod;
}
}
}
return c;
}
matrix pow_mod(matrix a,int b)//矩阵连乘
{
matrix s;
int i,j;
memset(s.f,0,sizeof(s.f));
for(i=0;i<4;i++)
s.f[i][i]=1;
while(b)
{
if(b&1)
s=mul(s,a);
a=mul(a,a);
b=b>>1;
}
return s;
}
int main()
{
int x,y,n;
while(scanf("%d%d%d",&n,&x,&y)!=EOF)
{
int i,j,k;
matrix e;
memset(e.f,0,sizeof(e.f));
x=x%mod;y=y%mod;
//建矩阵
e.f[0][0]=x*x%mod;e.f[1][0]=y*y%mod;e.f[2][0]=2*x*y%mod;
e.f[0][1]=e.f[0][3]=e.f[3][3]=1;e.f[0][2]=x;e.f[2][2]=y;
e=pow_mod(e,n);
printf("%I64d\n",(e.f[0][3]+e.f[1][3]+e.f[2][3]+e.f[3][3])%mod);
}
return 0;
}
/*
|x^2 1 x 1|
|f[n-1]^2 f[n-2]^2 f[n-1]*f[n-2] s[n-2]|*|y^2 0 0 0|=|f[n]^2 f[n-1]^2 f[n]*f[n-1] s[n-1]|
|2xy 0 y 0|
|0 0 0 1|
*/