首页 > 其他 > 详细

Fibonacci数列--矩阵乘法优化

时间:2016-02-03 21:42:32      阅读:248      评论:0      收藏:0      [点我收藏+]
Fibonacci数列
 
题目描述 

定义:f0=f1=1, fn=fn-1+fn-2(n>=2)。{fi}称为Fibonacci数列。

输入n,求fn mod q。其中1<=q<=30000。

输入描述 

第一行一个数T(1<=T<=10000)。

以下T行,每行两个数,n,q(n<=109, 1<=q<=30000)

输出描述 

文件包含T行,每行对应一个答案。

样例输入 

3

6 2

7 3

7 11

样例输出 

1

0

10

数据范围及提示 

1<=T<=10000

n<=109, 1<=q<=30000

 

 

矩阵乘法+Fibonacci:

  [fn,f(n-1)]=[f(n-1),f(n-2)]*[(1,1)

                                          (1,0)]{只能这样写了,不要打我}

#include<cstdio>
int n,p,t,b[3];
long long  a[3][3],c[3][3],d[3][3];
int ch(int x)
{
    c[1][1]=c[2][2]=1;
    c[1][2]=c[2][1]=0;//保证c[][]第一次与a[][]相乘时,值不变;
    while(x>1)
    {   
        int h=(x/2)*2;
        if(x!=h){
            for(int i=1;i<=2;i++)
            for(int j=1;j<=2;j++)
            for(int k=1;k<=2;k++) {d[i][j]+=(a[i][k]*c[k][j])%p;}/*将多出的a[][]存到c[][]中,不懂的回炉快速幂;*/
            for(int i=1;i<=2;i++)
                  for(int j=1;j<=2;j++) {c[i][j]=d[i][j];d[i][j]=0;}
        }
        for(int i=1;i<=2;i++)
        for(int j=1;j<=2;j++)
        for(int k=1;k<=2;k++) d[i][j]+=((a[i][k]%p)*(a[k][j]%p))%p;
        for(int i=1;i<=2;i++)
              for(int j=1;j<=2;j++) {a[i][j]=d[i][j];d[i][j]=0;}
        x=x/2;
    }
    for(int i=1;i<=2;i++)
    for(int j=1;j<=2;j++)
    for(int k=1;k<=2;k++) d[i][j]+=(a[i][k]*c[k][j])%p;//将多出的c[][]与a[][]相乘;
    return (d[1][1]+d[2][1])%p;//fn=f1*d[1][1]+f0*d[2][1],矩阵乘法化简后得到的;
}
int main()
{
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        for(int i=1;i<=2;i++)
          for(int j=1;j<=2;j++) d[i][j]=0;
        a[1][1]=a[1][2]=a[2][1]=1;
        a[2][2]=0;
        b[0]=1;b[1]=1;b[2]=2;//各种初始化;
        scanf("%d%d",&n,&p);
        if(n<3) printf("%d",b[n]%p);
        else{
            int ans=ch(n-1);
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

Fibonacci数列--矩阵乘法优化

原文:http://www.cnblogs.com/qingang/p/5180550.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!