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

  • 相关阅读:
    c语言 判断文件是否存在
    lua 二进制函数使用
    linux sort 多列正排序,倒排序
    free命令学习 输出理解
    nginx 配置实现逻辑预算
    nginx 使用ctx实现数据共享,修改上下文
    lua中的数学库
    tornado文件上传实例
    ajax技术初识与应用
    web框架--XSS攻击和CSRF请求伪造
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9192002.html
Copyright © 2011-2022 走看看