Another kind of Fibonacci
http://acm.hdu.edu.cn/showproblem.php?pid=3306
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3219 Accepted Submission(s): 1300
Problem 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
Author
wyb
Source
HDOJ Monthly Contest – 2010.02.06
题意
给定Sn的表达式求Sn的值
思路
由于n的值比较大,因此需要使用矩阵快速幂,问题的关键在于构造矩阵
又以上两式,可得
由此可构造矩阵
C++代码
注意:需使用G++提交
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long ll;
typedef vector<ll>vec;
typedef vector<vec>mat;
const ll mod=10007;
ll x,y,n;
mat mul(const mat &a,const mat &b)
{
mat c(a.size(),vec(b[0].size()));
for(int i=0;i<a.size();i++)
for(int j=0;j<b[0].size();j++)
for(int k=0;k<a[0].size();k++)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod;
return c;
}
mat qpow(mat a,ll n)
{
mat res(a.size(),vec(a.size()));
for(int i=0;i<res.size();i++) res[i][i]=1;
while(n)
{
if(n&1) res=mul(res,a);
a=mul(a,a);
n>>=1;
}
return res;
}
ll solve()
{
mat res(4,vec(1));
res[0][0]=2;//S[1]
res[1][0]=1;//A1^2
res[2][0]=1;//A0^2
res[3][0]=1;//A0*A1
if(n==0)
return 1;
else if(n==1)
return 2;
mat temp(4,vec(4));
temp[0][0]=1,temp[0][1]=x*x,temp[0][2]=y*y,temp[0][3]=2*x*y;
temp[1][0]=0,temp[1][1]=x*x,temp[1][2]=y*y,temp[1][3]=2*x*y;
temp[2][0]=0,temp[2][1]=1,temp[2][2]=0,temp[2][3]=0;
temp[3][0]=0,temp[3][1]=x,temp[3][2]=0,temp[3][3]=y;
temp=qpow(temp,n-1);
res=mul(temp,res);
return res[0][0];
}
int main()
{
while(~scanf("%lld%lld%lld",&n,&x,&y))
{
printf("%lld\n",solve());
}
}