fibonacci构造矩阵-总结

原文地址:

http://wenku.baidu.com/link?url=3PbnE95-IX6Sm26SQnkFkOb8xnqzzbcAqkAaPpiPZE-OXQGu3Aa6yrBR5Ot1a0a09-QYPQJ3i6maTlrQ0IX__j2AMA-tIUZ0QKw3LEYCTxi



Anotherkind of Fibonacci

Time Limit: 3000/1000 MS(Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 802    Accepted Submission(s): 326


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 anotherkind 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

Thereare several test cases.
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

 

 

Output

Foreach test case , output the answer of S(n).If the answer is too big , divide itby 10007 and give me the reminder.

 

 

Sample Input

2 1 1

3 2 3

 

 

Sample Output

6

196

 

 

 

下为解题报告:林大陈宇

 

该题为矩阵连乘问题,主要考虑以下公式:

 

f(n)=x*f(n-1)+y*f(n-2)

 

 

先看 s(n)=s(n-1)+f(n)^2;

右边出现了n,不可以的,只能出现n-1  或n-2

所以:s(n-1)=s(n-2)+f(n-1)^2;  右边有2项,s(n-2)和f(n-1)^2必须要有了

  S(n-2)-----------às(n-1)

   F(n-1)^2------à f(n)^2=[xf(n-1)+yf(n-2)]^2=出现了f(n-2)^2和2xyf(n-1)f(n-2),所以共4项

 

 

 

最左边是1个空的矩阵(4*4),也是我们要构造的矩阵(只要学过矩阵的人,就能把它算出来了吧)

 

然后代入矩阵连乘幂的模板算下就行了(该模板要会背着敲)

 

#include <iostream>

#include <stdio.h>

#include <cstring>

#define Mod 10007

using namespace std;

const int MAX = 4;

 

typedef  struct{

         int m[MAX][MAX];

}  Matrix;

MatrixP={1,1,0,0,

          0,0,0,0,

          0,1,0,0,

          0,0,0,0};

MatrixI={1,0,0,0,

          0,1,0,0,

          0,0,1,0,

          0,0,0,1};

Matrixmatrixmul(Matrix a,Matrix b) //矩阵乘法

{

       int i,j,k;

       Matrix c;

       for (i = 0 ; i < MAX; i++)

           for (j = 0;j < MAX;j++)

            {

                 c.m[i][j] = 0;

                 for (k = 0; k < MAX; k++)

                     c.m[i][j] += (a.m[i][k]*b.m[k][j])%Mod;

                 c.m[i][j] %= Mod;

            }

      return c;

}

 

Matrix quickpow(long long n)

{

      Matrix m = P, b = I;

              while (n >= 1)

       {

             if (n & 1)

                b = matrixmul(b,m);

             n = n >> 1;

             m =matrixmul(m,m);

      }

      return b;

}

 

 

int main()

{

    int n,x,y,sum;

    Matrix b;

/    while(cin>>n>>x>>y)

    {

      sum=0;

      x=x%Mod;

      y=y%Mod;

      P.m[1][1]=(x*x)%Mod;P.m[1][2]=(y*y)%Mod;P.m[1][3]=(2*x*y)%Mod;

     P.m[3][1]=x;P.m[3][3]=y;

       b=quickpow(n);

       for(int i=0;i<4;i++)

       sum+=b.m[0][i]%Mod;

       cout<<sum%Mod<<endl;

 

    }

        return 0;

}

 

注意: 注意每一步都要取模,别怕麻烦;

       对于x和y要是取负数的话(本题没有),则要(data%mod+mod)%mod;

       正的就直接data%mod就行;

       typedef struct{

         int m[MAX][MAX];

} Matrix;

该结构体的定义要注意,若将int  类型换成long long ,则运行时间会翻倍,可能会TLE,注意哦

 

----------------------------------------------------------------------------------------------------------------------

有兴趣的同学可以接着看,很有收获的,下面的方法和我的类似,我是把够造矩阵A放在左边,它是放在中间的,请用我的方法推1下,我给答案了。

 

 

构造常系数矩阵

(一)Fibonacci数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的第n项的快速求法(不考虑高精度).

解法:

考虑1×2的矩阵【f[n-2],f[n-1]】。根据fibonacci数列的递推关系,我们希望通过乘以一个2×2的矩阵,得到矩阵【f[n-1],f[n]】=【f[n-1],f[n-1]+f[n-2]】

很容易构造出这个2×2矩阵A,即:

 

所以,有【f[1],f[2]】×A=【f[2],f[3]】

又因为矩阵乘法满足结合律,故有:

【f[1],f[2]】×A n-1=【f[n],f[n+1]】

这个矩阵的第一个元素即为所求。

至于如何快速求出A n-1,相信大家都会,即递归地:n为偶数时,An=(A n/2)2;n为奇数时,An=(A n/2)2*A。

问题(一)解决。

 

我的方法:    (a)

还是填空:

     还没会吗? (a)式中左边的空矩阵就是让你填的A

 

(二)数列f[n]=f[n-1]+f[n-2]+1,f[1]=f[2]=1的第n项的快速求法(不考虑高精度).

解法:

仿照前例,考虑1×3的矩阵【f[n-2],f[n-1],1】,希望求得某3×3的矩阵A,使得此1×3的矩阵乘以A得到矩阵:【f[n-1],f[n],1】=【f[n-1],f[n-1]+f[n-2]+1,1】

容易构造出这个3×3的矩阵A,即:

 
 

问题(二)解决。

 

我的推法:

 

 

A是3*3的矩阵,填空吧

 

 

(三)数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的第n项的快速求法(不考虑高精度).

解法:

仿照前例,考虑1×4的矩阵【f[n-2],f[n-1],n,1】,希望求得某4×4的矩阵A,使得此1×4的矩阵乘以A得到矩阵:

【f[n-1],f[n],n+1,1】=【f[n-1],f[n-1]+f[n-2]+n+1,n+1,1】

容易构造出这个4×4的矩阵A,即:

 
 
 

问题(三)解决……

 

我自己的推法

 

 

接着填空:

 

 

 

四)数列f[n]=f[n-1]+f[n-2],f[1]=f[2]=1的前n项和s[n]的快速求法(不考虑高精度).

解法:

虽然我们有S[n]=F[n+2]-1,但本文不考虑此方法,我们想要得到更一般的方法。

考虑(一)的矩阵A,容易发现我们要求【f[1],f[2]】×(A+A2+A3+…+AN-1)。很多人使用一种很数学的方法构造一个2r*2r(r是A的阶数,这里为2)的矩阵来计算,这种方法比较麻烦且很慢,这里不再介绍。下面考虑一种新方法。

仿照之前的思路,考虑1×3的矩阵【f[n-2],f[n-1],s[n-2]】,我们希望通过乘以一个3×3的矩阵A,得到1×3的矩阵:

【f[n-1],f[n],s[n-1]】=【f[n-1],f[n-1]+f[n-2],s[n-2]+f[n-1]】

容易得到这个3×3的矩阵是:

 
 

然后…………容易发现,这种方法的矩阵规模是(r+1)*(r+1),比之前流行的方法好得多。

我用分块矩阵做过这题,但该方法的确应该推广,是主流的思想。

我的推法:

,所以矩阵见下,填空

为所求

 

 

 

(五)数列f[n]=f[n-1]+f[n-2]+n+1,f[1]=f[2]=1的前n项和s[n]的快速求法(不考虑高精度).

解法:

结合(三)(四),容易想到……

考虑1×5的矩阵【f[n-2],f[n-1],s[n-2],n,1】,

我们需要找到一个5×5的矩阵A,使得它乘以A得到如下1×5的矩阵:

【f[n-1],f[n],s[n-1],n+1,1】

=【f[n-1], f[n-1]+f[n-2]+n+1,s[n-2]+f[n-1],n+1,1】

容易构造出A为:

 
 
 
 

然后……问题解决。

 

我的推法:

 

,填空

 

为构造的矩阵。

 

 

陈宇于2012年7月15日


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值