zoukankan      html  css  js  c++  java
  • 欧几里得与扩展

    欧几里得:

    gcd递归定义:对于任意正整数b,gcd(a,b)= gcd(b,a mod b)。

    证明:

      

      只需要证明上面两者能相互整除。
    
      设gcd(a,b)= d,所以d | a 且 d | b。由带余除法可以得出:
    
      a mod b = a - qb。其中 q = └a / b┘.所以 a mod b 是a 和 b的一个线性方程组合,
      
      所以d |a mod b。又因为 d | b,所以 d | gcd(b,a mod b),即gcd(a,b)|gcd(b,a mod b)。
      
      证明gcd(b,a mod b)|gcd(a,b)和上述过程几乎一样。
    

      

    代码实现:

      

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 int a,b;
     5 int gcd(int a,int b)
     6 {
     7     if(a<b)swap(a,b);        //此处注意,why?仔细想想。 
     8     return a%b==0?b:gcd(b,a%b);
     9 }
    10 int main()
    11 {
    12     scanf("%d%d",&a,&b);
    13     printf("%d",gcd(a,b));
    14 }

    gcd 比较简单,接下来才是重头戏 --- 扩展。

    扩展欧几里得:

      这东西看似没啥用,实际其应用范围很广(逆元,不定方程...)。

      现在我们有这样一个问题:

        求解不定方程 ax + by = gcd(a,b).(假设 a >= b ).

     

    当 b=0 时有 gcd(a,b)=a,此时 x=1,y=0
    当 b 不为 0 时,根据 GCD 递归定理 gcd(a,b)=gcd(b, a mod b)
    可得 ax+ by=gcd(a, b)=gcd(b, a mod b)=bx′ +(a mod b)y′
    即 ax+by=bx′+(a mod b)y′ = bx′+(a−b)×⌊a/b⌋y′
    移项得 ax+by=bx′+(a mod b)y=ay'+b(x-⌊a/b⌋y)

    所以x=y',y=x'-
    ⌊ a/b ⌋y'.

      设(xo,yo)是不定方程 ax+by=m 的一组解,(a,b)=g,那么全部解为

        (xo+(b/g)t , yo - (a/g)t),其中 t 为所有整数.

      

    模板代码:

     1 #include <cstdio>
     2 int exgcd(int a, int b, int &x, int &y)        //非递归版 
     3 {
     4     int d;
     5     if (!b) x = 1, y = 0, d = a;
     6     else
     7     {
     8         d = exgcd(b, a % b, y, x);
     9         y -= (a / b) * x;
    10     }
    11     return d;
    12 }
    13 int exgcd(int a, int b, int &x, int &y)        //递归版 
    14 {
    15     int d;
    16     return !b ? (x = 1, y = 0, a) : (d = exgcd(b, a % b, y, x), y -= (a / b) * x, d);
    17 }
    18 int main()
    19 {
    20     int a, b, x, y;
    21     scanf ("%d%d", &a, &b);
    22     printf("%d
    ", exgcd(a, b, x, y));
    23     printf("%d %d
    ", x, y);
    24 }

    习题练习:

      NOIP 2012 同余方程

      求关于 x 的同余方程ax ≡ 1(mod b) 即求解 ax + by = 1  中的 x 值,注意题目要求 正整数。

      不是模板,胜似模板。

      代码:

     1 #include <cstdio>
     2 int exgcd(int a, int b, int &x, int &y) {
     3     int d;
     4     return !b ? (x = 1, y = 0, a) : (d = exgcd(b, a % b, y, x), y -= (a / b) * x, d);
     5 }
     6 int main()
     7 {
     8     int a, b, x, y;
     9     scanf ("%d%d", &a, &b);
    10     exgcd(a, b, x, y);
    11     int k=(0-x) /b;
    12     x=x+k*b;
    13     while(x<0){ x+=b; }     //处理负数 
    14     printf("%d", x);
    15 }

    作者:RMY

    出处:https://www.cnblogs.com/rmy020718/p/9192002.html

  • 相关阅读:
    企业如何选择数据分析架构?——谈谈3种架构的利弊
    jquery 拼接页面
    【感恩,回馈,展望】2018 ACOUG 年会盛大来袭!
    MySQL 数据库“十宗罪”(十大经典错误案例)
    break退出当前循环
    jquery 生成页面
    Python爬虫入门教程 35-100 知乎网全站用户爬虫 scrapy
    TypeError: Cannot read property '0' of undefined
    再砸4.35亿美元,LG疯狂扩建太阳能电池生产线
    再砸4.35亿美元,LG疯狂扩建太阳能电池生产线
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9192002.html
Copyright © 2011-2022 走看看