矩阵快速幂 CodeVS 1250 Fibonacci数列

来源:互联网 发布:vmware mac破解版下载 编辑:程序博客网 时间:2024/06/13 10:04

这里写图片描述

http://www.cnblogs.com/huxianglin/p/5995649.html

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

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

输入描述 Input Description
第一行一个数T(1<=T<=10000)。

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

输出描述 Output Description
文件包含T行,每行对应一个答案。

样例输入 Sample Input
3

6 2

7 3

7 11

样例输出 Sample Output
1

0

10

数据范围及提示 Data Size & Hint
1<=T<=10000

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

//普通快速幂 //14=1110//5(14)=5(8)*5(4)*5(2)*5(1)//5=101//矩阵优化快速幂 //f[n]=f[n-1]+f[n-2]//f[n]       = f[n-1]+f[n-2]  = 1  1  *  f[n-1]  //                                       f[n-2]//f[n]       = f[n-1]+f[n-2]  = 1  1  *  f[n-1]  //f[n-1]       f[n-1]          =1  0     f[n-2]#include<iostream>#include<cstdio>#include<cstring>using namespace std;int ans=1,n,t;int res[2][2];int xc[2][2];int q;int multi(int xa[][2],int xb[][2])//矩阵乘法 {    memset(xc,0,sizeof xc);    for(int i=0;i<2;i++)        for(int j=0;j<2;j++)            for(int k=0;k<2;k++)                xc[i][j]=(xc[i][j] + (xa[i][k]*xb[k][j])%q)%q;//    for(int i=0;i<2;i++)        for(int j=0;j<2;j++)            xa[i][j]=xc[i][j];//给xa[]赋值 error }void pw(int b){    memset(res,0,sizeof res);           //initial    for(int i=0;i<2;i++) res[i][i]=1;//单位矩阵     int tmp[2][2]={{1,1},{1,0}};       //initial    while(b)    {        if(b&1) {            multi(res,tmp);//res=res*tmp;        }        multi(tmp,tmp);        b>>=1;    }}int main(){    // 0 1 1 2 3 5 8 13 21 ...    //f[n]     =1  1   *   f[n-1]  = 1 1  ^ (n-1)  * f[1]    //f[n-1]    1  0       f[n-2]    1 0             f[0]    //2 f[n]     =1  1   *  1  f[n-1]  = 1 1  ^ (n-1)  *1 f[1]    //1 f[n-1]    1  0      1  f[n-2]    1 0            1 f[0]    cin>>t;    while(t)    {        scanf("%d%d",&n,&q);        pw(n+1);//这里要注意,f[0]=1,比之前的斐波那契数列往后一位         cout<<res[0][1]<<endl;        t--;    }}
原创粉丝点击