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