矩阵快速幂模板 斐波那契额版

Fibonacci数列的递推公式为 :

  • f[n]=f[n-1]+f[n-1]
  • f[1]=1
  • f[2]=1

矩阵形式的递推公式为:

 

 
 1 //通过矩阵快速幂来计算快速计算斐波那契额数列的步骤为
 2 //初始化单位矩阵,根据式子求出A.a[][](本题为通过f[n]=f[n-1]+f[n-2])
 3 //然后根据n的大小进行矩阵快速幂;
 4 //最后再用一个ans.A[][]初始化答案的值,比如斐波那契是f[1]=f[2]=1;
 5 //所以这里需要初始化ans.a[0][0]=1; ans.a[1][0]=1;
 6 //然后再ans=mat(B,ans);  注意mat()里面的顺序不能乱,矩阵乘法不满足交换律;
 7 #include<cstdio>
 8 #include<algorithm>
 9 #include<math.h>
10 #include<string.h>
11 using namespace std;
12 typedef long long ll;
13 const ll mod=2147493647;
14 struct node
15 {
16     ll a[10][10];
17 }ans,A,B;
18 node mat(node x,node y)
19 {
20     node c;
21     for(int i=0;i<=1;i++)
22     for(int j=0;j<=1;j++)   //这里开到1,因为只有2*2的矩阵
23         c.a[i][j]=0;        //矩阵多大开多大,不过假如矩阵为2*2,
24     for(int i=0;i<=1;i++)   //这里开比2大的数也是不会影响最终结果的。
25         for(int j=0;j<=1;j++)
26         for(int k=0;k<=1;k++)
27             c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
28     return c;
29 }
30 void quick_mod(ll n)
31 {
32     //初始化答案矩阵
33     memset(ans.a,0,sizeof(ans.a));
34     
35     //初始化单位矩阵
36     for(int i=0;i<=1;i++)
37     for(int j=0;j<=1;j++)
38         if(i==j) B.a[i][j]=1;
39         else B.a[i][j]=0;
40     
41     //初始化通过计算式子得出的矩阵(本题是斐波那契数列)f[n]=f[n-1]+f[n-2]
42     A.a[0][0]=A.a[0][1]=1;
43     A.a[1][0]=1;A.a[1][1]=0;
44     while(n){
45         if(n&1) B=mat(B,A);
46         A=mat(A,A);
47         n>>=1;
48     }
49 }
50 int main()
51 {
52     ll n;
53     while(scanf("%lld",&n)!=EOF){
54         if(n==1)      printf("1\n");
55         else if(n==2) printf("1\n");
56         else{
57             n-=2;
58             quick_mod(n);
59             ans.a[0][0]=1;
60             ans.a[1][0]=1;
61             ans=mat(B,ans);
62             printf("%lld\n",ans.a[0][0]);
63         }
64     }
65     return 0;
66 }

 

 

猜你喜欢

转载自www.cnblogs.com/pangbi/p/11832180.html