P1306斐波那契公约数(数论)待弄懂

结论gcd(f(n),f(m))=f(gcd(n,m));

证明是真的难懂,等我数论上路不知能否看懂,立个flag

因为比较的大,所以要用到矩阵快速幂求斐波那契数列

 1 #include<iostream>
 2 #define ll long long
 3 using namespace std;
 4 struct matix
 5 {
 6     ll m[2][2];
 7 }mp;
 8 const int mod = 1e8;
 9 matix mul(matix a,matix b)//矩阵乘法
10 {
11     matix t;//answer
12     for(ll i=0;i<=1;i++)
13     {
14         for(ll j=0;j<=1;j++)
15         {
16             t.m[i][j]=0;
17         }
18     }
19     for(ll i=0;i<=1;i++)//普通的矩阵乘法
20     {
21         for(ll j=0;j<=1;j++)
22         {
23             for(ll k=0;k<=1;k++)
24             {
25                 t.m[i][j]+=(a.m[i][k]%mod*b.m[j][k]%mod)%mod;
26                 t.m[i][j]%=mod;
27             }
28         }
29     }
30     return t;
31 }
32 void cal(ll n)
33 {
34     matix t;
35     t.m[0][0]=t.m[1][0]=t.m[0][1]=1;
36     t.m[1][1]=0;
37     for(ll i=0;i<=1;i++)
38     {
39         for(ll j=0;j<=1;j++)
40         {
41             if(i==j)
42             {
43                 mp.m[i][j]=1;
44             }
45             else
46             {
47                 mp.m[i][j]=0;
48             }
49         }
50     }
51     //在此之前的是初始化
52     while(n)//一般快速幂,(矩阵快速幂就是把乘变成了矩阵乘法)
53     {
54         if(n&1)
55         {
56             mp=mul(t,mp);
57         }
58         n>>=1;
59         t=mul(t,t);
60     }
61 }
62 ll gcd(ll a,ll b)//计算最大公约数,辗转相除
63 {
64     while(b)
65     {
66         ll Rem = a % b;
67         a = b;
68         b = Rem;
69     }
70     return a;
71 }
72 int main()
73 {
74     ll n,m;
75     cin>>n>>m;
76     int t=gcd(n,m);
77     cal(t-1);//计算f(t)
78     cout<<mp.m[0][0];
79     return 0;
80 }
posted on 2020-01-19 21:26  greenofyu  阅读(185)  评论(0编辑  收藏  举报