HDU3306 Another kind of Fibonacci【矩阵快速幂】

本文介绍了一种解决大规模Fibonacci数列变种问题的方法,通过矩阵快速幂算法高效计算特定形式的Fibonacci数列的平方和。针对给定的递推公式A(N)=X*A(N-1)+Y*A(N-2),文章详细阐述了如何构建矩阵并应用快速幂技巧,以避免直接递归带来的巨大计算成本。
摘要由CSDN通过智能技术生成

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的值比较大,因此需要使用矩阵快速幂,问题的关键在于构造矩阵

S_{n}=S_{n-1}+(A_{n})^2

A_{n}=X\times A_{n-1}+Y\times A_{n-2}

又以上两式,可得

S_{n}=S_{n-1}+X^2A_{n-1}^2+Y^2A_{n-2}^2+2XYA_{n-1}A_{n-2}

由此可构造矩阵

\begin{pmatrix} S_{n}\\ A_{n}^2\\ A_{n-1}^2\\ A_{n}A_{n-1} \end{pmatrix}=\begin{pmatrix} 1\times S_{n-1}+X^2\times A_{n-1}^2 +Y^2\times A_{n-2}+2XY\times A_{n-1}A_{n-2}\\ 0\times S_{n-1}+X^2\times A_{n-1}^2 +Y^2\times A_{n-2}+2XY\times A_{n-1}A_{n-2}\\ 0\times S_{n-1}+1\times A_{n-1}^2 +0\times A_{n-2}+0\times A_{n-1}A_{n-2} \\ 0\times S_{n-1}+X\times A_{n-1}^2 +0\times A_{n-2}+Y\times A_{n-1}A_{n-2} \end{pmatrix}=\begin{pmatrix} 1 & X^2 &Y^2 &2XY\\ 0& X^2& Y^2& 2XY\\ 0& 1& 0 & 0\\ 0& X& 0 & Y \end{pmatrix} \times \begin{pmatrix} S_{n-1}\\ A_{n-1}^2\\ A_{n-2}^2\\ A_{n-1}A_{n-2} \end{pmatrix} =\begin{pmatrix} 1 & X^2 &Y^2 &2XY\\ 0& X^2& Y^2& 2XY\\ 0& 1& 0 & 0\\ 0& X& 0 & Y \end{pmatrix}^{n-1} \times \begin{pmatrix} S_{1}\\ A_{1}^2\\ A_{0}^2\\ A_{1}A_{0} \end{pmatrix} 

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());
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值