斐波那契公约数 【数论】

题目

  洛谷 https://www.luogu.org/problemnew/show/P1306

  对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少?

输入输出格式

  输入格式:

  两个正整数n和m。(n,m<=10^9)

  注意:数据很大

  输出格式:

  Fn和Fm的最大公约数。

  由于看了大数字就头晕,所以只要输出最后的8位数字就可以了。(%100000000)

分析  

  对于 gcd(F[n],F[m])  假令 n<m  F[n]=x ,F[n+1]=y;

  F[n+2]=x+y    =F[1]*x+F[2]*y
  F[n+3]=x+2*y      =F[2]*x+F[3]*y
  F[n+4]=2*x+3*y   =F[3]*x+F[4]*y
  ...
  F[m]=F[m-n-1]*x+F[m-n]*y 又F[n]=x;
  则Gcd(F[n],F[m])=Gcd(F[n],F[n+1]*F[m-n])

  又F[n+1]-F[n]=F[n-1]
  且Gcd(F[n+1],F[n]) =Gcd(F[n],F[n+1]-F[n]) (辗转相减法,辗转相除的变式)
            =Gcd(F[n],F[n-1])
            =Gcd(F[n-1],F[n-2]) (同理)
            =Gcd(F[3],F[2])=1;

  故Gcd(F[n],F[m])=Gcd(F[n],F[n+1]*F[m-n])=Gcd(F[n],F[m-n])
                      =Gcd(F[m-n],F[m-2*n]) (同理)
                      .....
                     =Gcd(F[Gcd(n,m)],F[Gcd(n,m)]) (辗转相减法的变形)
  得到Gcd(F[n],F[m])=F[Gcd(n,m)];

  对于F[Gcd(n,m)]的求解,运用矩阵快速幂优化(矩阵乘幂优化线性递推式)

代码

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int mod=100000000;
 9 int N,M;
10 struct data{
11     int r,c;
12     ll a[3][3];
13     data(){
14         memset(a,0,sizeof(a));
15     }
16     friend data operator*(data a,data b){
17         data c;
18         c.r=a.r;c.c=b.c;
19         for(int i=1;i<=a.r;i++)
20         for(int k=1;k<=a.c;k++)
21         for(int j=1;j<=b.c;j++)
22          (c.a[i][j]+=a.a[i][k]*b.a[k][j])%=mod;
23         return c;
24     }
25 };
26 int Gcd(int x,int y){
27     if(y==0) return x;
28     return Gcd(y,x%y);
29 }
30 ll Fast(int t){
31     data a,b,c;
32     a.r=2,a.c=2;
33     a.a[1][1]=1,a.a[1][2]=1,a.a[2][1]=1;
34     b.r=2,b.c=1;
35     b.a[1][1]=b.a[2][1]=1;
36     while(t){
37         if(t&1) b=a*b;
38         a=a*a;
39         t=t>>1;
40     }
41     return b.a[1][1];
42 }
43 int main(){
44     scanf("%d%d",&N,&M);
45     int t=Gcd(N,M);
46     if(t<=2) cout<<1<<endl;
47     else cout<<Fast(t-2);
48     return 0;
49 }

猜你喜欢

转载自www.cnblogs.com/Aloyd/p/9299283.html