求第n个Fibonacci数mod p的值
题意:给定n和p,求第n个Fibonacci数mod p的值,n不超过2^31。
思路:现在我们需要构造一个2 x 2的矩阵,使得它乘以(a,b)得到的结果是(b,a+b)。每多乘一次这个矩阵,这两个数就会多迭代一次。那么,我们把这个2 x 2的矩阵自乘n次,再乘以(0,1)就可以得到第n个Fibonacci数了。不用多想,这个2 x 2的矩阵很容易构造出来:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio>
2 #include <cstring>
3 #include <cmath>
4 #include <string>
5 #include <algorithm>
6 #include <iostream>
7 using namespace std;
8
9 typedef struct In{
10 int m[3][3];
11 }Matrix;
12 Matrix init,unit,F;
13 int n,m;
14
15 void Init(){
16 for(int i=1;i<=2;i++)
17 for(int j=1;j<=2;j++){
18 if(i==1&&j==1) init.m[i][j]=0;
19 else init.m[i][j]=1;
20 unit.m[i][j]=(i==j);
21 F.m[i][j]=0;
22 }
23 F.m[1][1]=0;
24 F.m[2][1]=1;
25 }
26
27 Matrix Mul(Matrix a,Matrix b){
28 Matrix c;
29 for(int i=1;i<=2;i++)
30 for(int j=1;j<=2;j++){
31 c.m[i][j]=0;
32 for(int k=1;k<=2;k++){
33 c.m[i][j]+=a.m[i][k]*b.m[k][j];
34 c.m[i][j]%=m;
35 }
36 }
37 return c;
38 }
39
40 Matrix Pow(Matrix a,Matrix b){
41 while(n){
42 if(n&1) b=Mul(a,b);
43 a=Mul(a,a);
44 n>>=1;
45 }
46 return b;
47 }
48
49 int main(){
50
51 // freopen("data.in","r",stdin);
52 // freopen("data.out","w",stdout);
53
54 while(scanf("%d%d",&n,&m)!=EOF){
55 Init();
56 Matrix x=Pow(init,unit);
57 x=Mul(x,F);
58 printf("%d\n",x.m[2][1]%m);
59 }
60 return 0;
61 }