HDU 3306:传送门
Another kind of Fibonacci
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 231 – 1
X : 2<= X <= 231– 1
Y : 2<= Y <= 231 – 1
题意很简单:An=x*A(n-1)+y*A(n-2);A0=1,A1=1;S(n)=A0^2+A1^2+A2^2+…………+An^2;求Sn; 已知n,x,y;
思路:先找上一项和下一项的关系。(需要什么类型,求什么类型)
An=x*A(n-1) +y*A(n-2);( A(n-1) 类型(一次方型)已知 )
求Sn:( Sn 类型(总和型)未知 )
Sn = Sn-1 + An^2 ; ( An^2 类型(平方型)未知 )
An^2=(x*A(n-1) +y*A(n-2))*(x*A(n-1) +y*A(n-2))= x^2*A(n-1)^2 + 2*x*y*A(n-1)*A(n-2) + y^2*A(n-2)^2 ;
( A(n-1)*A(n-2) 类型(乘积型)未知 )
An*A(n-1) =( x*A(n-1) +y*A(n-2) )*A(n-1) = x * A(n-1)^2 + y * A(n-1)*A(n-2) ; (这个式子 开始的那个A(n-1) 不敢拆)
( 所有类型都已知 )
所有的关系都有了就可以写矩阵了
初始矩阵 :
S(n-2), A(n-1)^2 , A(n-2)^2 , A(n-1)*A(n-2) ;
系数矩阵:
1 0 0 0
1 x^2 1 x
0 y^2 0 0
0 2*x*y 0 y
下一项矩阵:
S(n-1), An^2 , A(n-1)^2 ,An*A(n-1) ;
第0项矩阵为 S0 , A1^2 , A0^2 ,, A1*A0
及1 1 1 1
AC代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#define LL long long
#include<iostream>
#define mod 10007
using namespace std;
struct node
{
int a[10][10];
};
node operator * (node a,node b)
{
node c;
memset(c.a,0,sizeof(c.a));
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
{
for(int k=0; k<4; k++)
c.a[i][j]+=a.a[i][k]*b.a[k][j];
c.a[i][j]%=mod;
}
return c;
}
node ans,a;
int x,y,n;
void init()
{
memset(ans.a,0,sizeof(ans.a));
memset(a.a,0,sizeof(a.a));
for(int i=0;i<4;i++)
ans.a[0][i]=1;
a.a[0][0]=1;
a.a[1][0]=1;a.a[1][1]=(x*x)%mod;a.a[1][2]=1;a.a[1][3]=x;
a.a[2][1]=(y*y)%mod;//这里的%mod很有必要,不然下次乘的时候可能会超int,
a.a[3][1]=(2*x*y)%mod;a.a[3][3]=y;
}
void pow1(int k)
{
init();
while(k)
{
if(k%2)ans=ans*a;
a=a*a;
k=k>>1;
}
printf("%d\n",ans.a[0][0]);
}
int main()
{
while(~scanf("%d%d%d",&n,&x,&y))
{
x%=mod;
y%=mod;
pow1(n);
}
}