zoukankan      html  css  js  c++  java
  • 最大公约数

    •最大公约数:两个不同时为0的a与b的公约数中最大的称为最大公约数,记为gcd(a,b)
    •最大公约数的基本性质:
    •gcd(a,b)=gcd(b,a)
    •gcd(a,b)=gcd(-a,b)
    •gcd(a,b)=gcd(|a|,|b|)
    •gcd(a,0)=|a|
    •gcd(a,k*a)=|a|
    •gcd(a*n,b*n)=n*gcd(a,b)
    •若d|a且d|b,则d|gcd(a,b)
    •若n|ab且gcd(a,n)=1,则n|b
    •若gcd(a,p)=1且gcd(b,p)=1,则gcd(a*b,p)=1
    问题一:给定a,b,计算gcd(a,b)
    •方法1:枚举法
      从min(a,b)到1枚举x,并判断x是否能同时整除a和b,如果可以则输出x退出循环。时间复杂度为O(min(a,b))。
    •方法2:分解质因子
      对a,b分别分解质因子,$a={p_1}^{x_1}*{p_2}^{x_2}*...{p_n}^{x_n}$,$b={p_1}^{y_1}*{p_2}^{y_2}*...{p_n}^{y_n}$,其中xi,yi>=0且不会同时为0(1<=i<=n),则    
        gcd(a,b)=${p_1}^{min({x_1},{y_1})}$*${p_2}^{min({x_2},{y_2})}$*...${p_n}^{min({x_n},{y_n})}$。
      如何分解a和b?
      以a为例,根据唯一因子分解定理,从2开始依次枚举因子i,如果i能整除a,则把i从a中分解出去,再考虑i+1。如果a是合数,则一定存在a=b*c(b<=c,b!=1,c!=n),则有b*b<=b*c=a,b<=$sqrt a$。即如果a是合数则在2到$sqrt a$内一定存在质因子,循环i执行到i*i>a为止,如果a不等于1,则a也是素因子。
    •方法3:欧几里得算法
    •定理:gcd(a,b)=gcd(b,a mod b)
    ••证明(1):
      设gcd(a,b)=p,则有a=a'*p,b=b'*p,gcd(a',b')=1
      a mod b=a-$a over b$*b=p*(a'-$a over b$*b')
      gcd(b,a mod b)=gcd(b'*p,p*(a'-$a over b$*b'))=p*gcd(b',a'-$a over b$*b')
      证明gcd(b',a'-$a over b$*b')=1:
      反证法,如果gcd(b',a'-$a over b$*b')=t(t>1)设b'=b''*t,a'-$a over b$*b'=c'*t,则有a'=$aover b$*b''*t+c'*t=t*($a over b$*b''+c')$显然t|b',t|a',与gcd(a',b')=1相矛盾
      所以gcd(b,a mod b)=p=gcd(a,b)
    ••证明(2):
      a可以表示成a = kb + r,则r = a mod b
      假设d是(a,b)的一个公约数,则有d|a, d|b,而r = a - kb,因此d|r
      因此d是(b,a mod b)的公约数
      假设d是(b,a mod b)的公约数,则d|b,d|r,但是a = kb +r
      因此d是(a,b)的公约数
      因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
    ••时间复杂度分析(1):
      根据(a,b)=>(b,a mod b),
      设a>b:
      ①当a>=2*b时,b<=a/2,规模至少缩小一半;
      ②当a<2*b时,a mod b<a/2
      时间复杂度为O($log_N$)
    ••时间复杂度分析(2):
    •••定理:斐波那契数列f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2)(n>=2)。a>b>=1且Euclid(a,b)执行了k(k>=1)次递归调用,则a>=f(k+2),b>=f(k+1)
    ••••证明:数学归纳法
         ①当k=1时,b>=f(2)=1,因a>b,所以a>=2=f(3),成立。
         ②假设当k=x时成立,即满足a>=f(x+2),b>=f(x+1),当k=x+1时:
         第一次递归调用(a,b)变成(b,a mod b),由于从(b,a mod b)开始递归调用了x次完成,所以满足:
         b>=f(x+2),a mod b>=f(x+1)
         又因为a>b,所以a>=b+a mod b>=f(x+2)+f(x+1)=f(x+3)
         即当k=x+1时,a>=f(x+3),b>=f(x+2),同样满足结论!
         ③得证!
    ••••计算f(n)的公式:参见附录
    ••••时间复杂度O(${log_phi}^{{sqrt 5 *b} over {gcd(a,b)}}$    )
    •方法4:二进制法
      ①a<b时,gcd(a,b)=gcd(b,a)
      ②a=b时,gcd(a,b)=a
      ③a,b同为偶数时,gcd(a,b)=gcd(a/2,b/2)
      ④a为偶数,b为奇数时,gcd(a,b)=gcd(a/2,b) 
      ⑤a为奇数,b为偶数时,gcd(a,b)=gcd(a,b/2)
      ⑥a,b同为奇数时,gcd(a,b)=gcd(a-b,b)
      ⑦适合求高精度数的最大公约数
     
    附录A:
    http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
    附录B:
     方法二:
     1      void Decompose()
     2      {
     3          for(int x=2;x*x<=min(a,b);x++)
     4          {
     5              while (a % x==0 && b % x==0){a/=x;b/=x;ans*=x;}
     6              while (a % x==0)a/=x;
     7              while (b % x==0)b/=x;
     8          } 
     9          if (a % b==0)ans*=b;
    10          else if (b % a==0)ans*=a;
    11          printf("%d",ans);
    12      }
    方法三
    1 int gcd(int a,int b) { return b ? gcd(b,a%b) : a;}
    方法四
    1 int Gcd(int m,int n){
    2     if (m==n) return m;
    3     if (m<n) return Gcd(n,m);
    4     if (m & 1==0) return (n & 1==0)? 2*Gcd(m/2,n/2):Gcd(m/2,n);
    5     return (n & 1==0)? Gcd(m,n/2): Gcd(n,m-n);
    6 }

     附录C

    计算斐波那契数列的方法

     
  • 相关阅读:
    SpringBoot Rabbitmq接收消息
    SpringBoot Rabbitmq发送消息
    Rabbitmq 介绍
    Eureka 使用Spring cloud config 管理中心启动
    Spring Cloud Config 搭建Config 服务
    Eureka 向Server中注册服务
    Eureka 配置
    给定一些分割符,给定一个待分割的字符串,打印出分割之后最长的字符串
    给定N个整数,乱序,分行打印每个数字和其位置
    给定一个整数,求它的二进制表示中有多少个1
  • 原文地址:https://www.cnblogs.com/hjj1871984569/p/5931198.html
Copyright © 2011-2022 走看看