• 数论初步?


    更新:之前整除的符号写反了……(手动慌张分析)

    这种算法及能解决的问题在高中课本《初等数论初步》就有,写这篇博客是希望初中生能看懂。
    前置技能:(aLeftrightarrow b)意思是a当且仅当b。简单来说若(aLeftrightarrow b),则一定满足①(a)成立时(b)一定成立;②(b)成立时(a)一定成立;③(a)不成立时(b)一定不成立;④(b)不成立时(a)一定不成立。
    (aequiv bpmod c)是同余符号,意思是(amod c=bmod c)
    整除符号:(amid bLeftrightarrow bmod a=0)

    〇、辗转相除法

    众所周知,求两个正整数的最大公约数可以通过以下式子来递归求解。
    (gcd(a,b)=egin{cases}b & amid b \ gcd(b,amod b) & a otmid bend{cases})
    然而很多人不知道为什么 (gcd(a,b)=gcd(b,amod b);(a otmid b)) 是对的。下面给出证明。
    证明(c = amod b, a ÷ b = kcdotscdots c, gcd(a,b) = p, gcd(b, amod b) = q)
    $∵amid p, ∴kamid p, $ 又 (∵bmid p, ∴)

    一、扩展欧几里得算法

    模板 已知(a, b(a≥b)),求不定方程(ax+by=gcd(a,b))的任意一组整数解。

    定理1 (ax+by=gcd(a,b))必有整数解。
    证明 下面给出一种递归的求解方式。当(amid b)时,(gcd(a,b)=a),原式化为(ax+by=a),移项得(a(x-1)+by=0),显然有一组解为(egin{cases}x=1\y=0end{cases})(反正我们只要一组解)。
    (a otmid b)时,(gcd(a,b)=gcd(b,amod b))。若(ax+by=gcd(a,b))有整数解,根据归纳法,则(bx+(amod b)y=gcd(b,amod b))也有整数解。(此处难懂,请反复推敲)
    (ax+by=gcd(a,b))的一组解为(egin{cases}x=x_1\y=y_1end{cases})(bx+(amod b)y=gcd(b,amod b))的一组解为(egin{cases}x=x_2\y=y_2end{cases}),则$$egin{matrix}
    ax_1+by_1 & = & gcd(a,b)
    & & ||
    bx_2+(amod b)y_2 & = & gcd(b,amod b)
    end{matrix}$$$$egin{align}
    ∴ax_1+by_1&=bx_2+(amod b)y_2
    ext{又}∵amod b&=a-leftlfloorfrac{a}{b} ight floor
    b
    ∴ax_1+by_1&=bx_2+(a-leftlfloorfrac{a}{b} ight floorb)y_2
    ext{整理得}ax_1+by_1&=ay_2+b(x_2-leftlfloorfrac{a}{b} ight floor
    y_2)end{align}$$$$∴egin{cases}x_1=y_2y_1=x_2-leftlfloorcfrac{a}{b} ight floory_2end{cases}$$
    将结果层层回溯即可。

    void exgcd(int a, int &x, int b, int &y) {
      if (a % b == 0) {
        x = 1; y = 0;
      } else {
        exgcd(b, y, a%b, x);
        y -= a / b * x;
      }
    }
    

    二、求解形如(ax+by=c)的不定方程的整数解

    例1 已知(a, b, c(a≥b)),求不定方程(ax+by=c)的任意一组整数解。

    定理2 (cmidgcd(a,b)Leftrightarrow ax+by=c)一定有整数解。
    证明 根据定理1,(ax+by=gcd(a,b))一定有整数解,设其中一组解为(egin{cases}x=x_1\y=y_1end{cases})。将解代入原式得(ax_1+by_1=gcd(a,b))
    又设(a'=cfrac{a}{gcd(a,b)}, b'=cfrac{b}{gcd(a,b)})(后面的证明还会用到),(∵amidgcd(a,b),)(bmidgcd(a,b),)(∴a',b'inBbb{Z})
    方程两边同除以(gcd(a,b)),得(a'x+b'y=cfrac{c}{gcd(a,b)}),易发现方程左边为整数,∴当方程右边不为整数(而是小数)时,原方程无解。即当(c otmidgcd(a,b))时,原方程无解。
    而当(cmidgcd(a,b))时,在第一段证明中的方程(ax_1+by_1=gcd(a,b))两边同乘(cfrac{c}{gcd(a,b)}),得(cfrac{ac}{gcd(a,b)}x+cfrac{bc}{gcd(a,b)}y=c),∴可得一组整数解(egin{cases}x=frac{c}{gcd(a,b)}x_1\y=frac{c}{gcd(a,b)}y_1end{cases})

    int gcd(int a, int b) {
      return a % b ? gcd(b, a % b) : b;
    }
    int main() {
      /*输入*/
      int gcd_ab = gcd(a,b);
      if (c % gcd_ab == 0) {
        exgcd(a, x, b, y);
        x *= c / gcd_ab;
        y *= c / gcd_ab;
        printf("%d %d
    ", x, y);
      } else
        printf("No Solution
    ");
     return 0;
    }
    

    NeXT. 如果要求不定方程的所有整数解呢?
    定理3 若不定方程的一组整数解为(egin{cases}x=x_1\y=y_1end{cases}),则它的任意一组整数解都可以表示为(egin{cases}x=x_1+kb’\y=y_1-ka'end{cases})
    证明 设除了已知的一组整数解(egin{cases}x=x_1\y=y_1end{cases})之外,原式的另一个整数解为(egin{cases}x=x_2\y=y_2end{cases})。显然(ax_1+by_1=ax_2+by_2)(∴a(x_2-x_1)=b(y_1-y_2))。方程两边同除以(gcd(a,b)),得(a'(x_2-x_1)=b'(y_1-y_2))。两边再同除以(b'),得(cfrac{a'(x_2-x_1)}{b'}=y_1-y_2)。显然右边是整数,∴左边是整数。又$∵gcd(a,b)=1, $ $∴a'mid b', $ (∴x_2-x_1mid b',) (∴x_2-x_1=kb')(x_2=x_1+kb')。同理可得(y_2=y_1-ka')
    当然,不会真有这么智障的问题(因为不可能全部输出),而是会问大于/不小于/小于/不大于某个范围的最小/大值。

    例2 已知(a, b, c(a≥b)),求(displaystylemin_{ax+by=c,xinBbb{Z^*}}x)

    定理4(c|gcd(a,b)),则不定方程(ax+by=c)(x=[0,b'-1])间一定有唯一解。
    证明 根据定理3,

    (TODO)乘法逆元、欧拉函数

  • 相关阅读:
    axb_2019_fmt32 盲打和格式化字符串
    ciscn_2019_final_3 需要避开当前free的chunk的下一个chunk不能超过arena的边界
    xdctf2015_pwn200
    valarray类
    Mysql 常用命令.
    如何处理IO
    等号两边自动添加括号
    Request JSON
    开机小脚本自动打开sublime text 和git-bash
    git 同步勾子
  • 原文地址:https://www.cnblogs.com/P6174/p/7403550.html
Copyright © 2020-2023  润新知