nefu Another kind of Fibonacci 458 (矩阵连乘)

Another kind of Fibonacci

Problem : 458

Time Limit : 1000ms

Memory Limit : 65536K

description

As we all known , the Fibonacci series : F(0) = 1, F(1) = 1, F(N) = F(N - 1) + F(N - 2) (N >= 2).Now we define another kind of Fibonacci : A(0) = 1 , A(1) = 1 , A(N) = X * A(N - 1) + Y * A(N - 2) (N >= 2).And we want to Calculate S(N) , S(N) = A(0)^2 +A(1)^2+……+A(n)^2.

input

There are several test cases.
Each test case will contain three integers , N, X , Y .
N : 2<= N <= 2^31 – 1
X : 2<= X <= 2^31– 1
Y : 2<= Y <= 2^31 – 1

output

For each test case , output the answer of S(n).If the answer is too big , divide it by 10007 and give me the reminder.

sample_input

2 1 1 
3 2 3

sample_output

6
196

hint

source

题意:

已知f(0)=f(1)=1,并且有递推关系式为f(n)=x*f(n-1)+y*f(n-2),定义s(n)=(f(0))^2+(f(1))^2+......+(f(n))^2,给定n,x,y,求s(n)%10007的值。

 

/*
思路:
s[n]=s[n-1]+f(n)^2;
f[n]^2=(x*f[n-1]+y*f[n-2])^2;
拆开得:f[n]=x^2*f[n-1]^2+2*x*y*f[n-1]*f[n-2]+y^2*f[n-2]^2;
所以可构造矩阵为:
 s[n]                    1  x^2  y^2  2*x*y         s[n-1]
 f[n]^2                  0  x^2  y^2  2*x*y    *    f[n-1]^2
 f[n-1]^2         =      0  1    0    0             f[n-2]^2
 f[n]*f[n-1]             0  x    0    y             f[n-1]*f[n-2]
进一步化简得:
  s[n]                    1  x^2  y^2  2*x*y  ^(n-1)       s[1]
 f[n]^2                  0  x^2  y^2  2*x*y          *    f[1]^2
 f[n-1]^2         =      0  1    0    0                   f[0]^2
 f[n]*f[n-1]             0  x    0    y                   f[1]*f[0]
由以上可得:
*/

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
#define M 10007
#define N 4
using namespace std;
struct mat
{
	ll m[N][N];
};
mat I=
{
	1,0,0,0,
	0,1,0,0,
	0,0,1,0,
	0,0,0,1
};
mat multi(mat a,mat b)
{
	mat c;
	int i,j,k;
	for(i=0;i<N;i++)
	{
		for(j=0;j<N;j++)
		{
			c.m[i][j]=0;
			for(k=0;k<N;k++)
				c.m[i][j]+=a.m[i][k]*b.m[k][j]%M;
			c.m[i][j]%=M;
		}
	}
	return c;
}
mat power(mat a,ll k)
{
	mat ans=I,p=a;
	while(k)
	{
		if(k&1)
		{
			ans=multi(ans,p);
			k--;
		}
		k>>=1;
		p=multi(p,p);
	}
	return ans;
}
int main()
{
	ll n,x,y;
	mat a;
	while(scanf("%lld%lld%lld",&n,&x,&y)!=EOF)
	{
		a.m[0][0]=1;a.m[0][1]=x%M*x%M;a.m[0][2]=y%M*y%M;a.m[0][3]=2*x%M*y%M;
		a.m[1][0]=0;a.m[1][1]=x%M*x%M;a.m[1][2]=y%M*y%M;a.m[1][3]=2*x%M*y%M;
		a.m[2][0]=0;a.m[2][1]=1;a.m[2][2]=0;a.m[2][3]=0;
		a.m[3][0]=0;a.m[3][1]=x%M;a.m[3][2]=0;a.m[3][3]=y%M;
		mat ans=power(a,n-1);
		ll cnt=(2*ans.m[0][0]%M+ans.m[0][1]%M+ans.m[0][2]%M+ans.m[0][3]%M)%M;
		printf("%lld\n",cnt);
	}
	return 0;
}


 

 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值