Fibonacci数列(codevs 1250)
题目描述 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
/* 矩阵乘法求斐波那契数列 */ #include<cstdio> #include<iostream> #define ll long long using namespace std; ll a[3][3],b[3][3],c[3][3],ans[3][3],n,mod; void work() { b[1][1]=ans[1][1]=0; b[1][2]=ans[1][2]=1; b[2][1]=ans[2][1]=1; b[2][2]=ans[2][2]=1; while(n) { if(n&1) { for(int k=1;k<=2;k++) for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) c[i][j]=(c[i][j]+(ans[i][k]*b[k][j]%mod)%mod); for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) ans[i][j]=c[i][j],c[i][j]=0; } for(int k=1;k<=2;k++) for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) c[i][j]=(c[i][j]+(b[i][k]*b[k][j]%mod)%mod); for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) b[i][j]=c[i][j],c[i][j]=0; n/=2; } printf("%lld\n",(ans[1][1]+ans[1][2])%mod); } int main() { int T; scanf("%d",&T); while(T--) { cin>>n>>mod; if(n<=2)printf("%lld\n",n); else n--,work(); } return 0; }