zoukankan      html  css  js  c++  java
  • [学习笔记] 扩展欧几里得算法

    某王 课上给我们罗列一些算法,突然发现我竟然连扩欧都不会。。。

    嗯,这篇博客不能被某王看到,不然要被打。。。

    用途:

    ax≡k*gcd(a,b)  [mod b]   这种问题就可以用扩欧来解决。

    核心思路:

    用类似欧几里得算法(又名辗转相除法)转化成具有递推关系的式子来求解。

    推导过程:

    ax≡k*gcd(a,b)  [mod b]很显然可以写成:ax-by=k*gcd(a,b),这里为了方便我们把它写成:ax+by=k*gcd(a,b)把y取个反就好了。

    那么为什么这个方程保证有解呢?

    我们另ax+by=m。

    因为a%gcd(a,b)=0,b%gcd(a,b)=0,所以m%gcd(a,b)=0,所以m=k*gcd(a,b)是肯定有解的。

    那么这个解应该怎么来求呢?

    我们再写一个方程:b*x1+a%b*y1=k*gcd(b,a%b)=k*gcd(a,b)=a*x+b*y

    继续转换:b*x1+(a-[a/b]下取整*b)*y1=a*x+b*y

    再把a,b当作主元:a*y1+b*(x1-[a/b]下取整*y1)=a*x+b*y

    得到:x=y1,y=x1-[a/b]下取整*y1

    让我们把b*x1+a%b*y1当成原方程再写一个方程:a%b*x2+b%(a%b)*y2=k*gcd(a%b,b%(a%b))=k*gcd(b,a%b)

    那么我们是不是又能够得出:x1=y2,y1=x2-[a/b]下取整*y2

    我们是不是可以一直这样写下去直到b为0,这不就和欧几里得算法差不多。

    最后一个方程就是:c*xn+0*yn=gcd(c,0)

    因为gcd(c,0)=c,0*yn=0所以xn=0,而yn可以为任意值。(建议给yn取0,这样不容易爆long long)

    然后我们再回上去求解就行。

    代码实现:(这里以洛谷P1082为例)

    var
        x,y,a,b,t:int64;
    procedure exgcd(a,b:int64);
    begin
        if b=0 then
        begin
            x:=1;  y:=0;
            exit;
        end;
        exgcd(b,a mod b);
        t:=x; x:=y;
        y:=t-a div b*y;
    end;
    begin
        read(a,b);
        exgcd(a,b);
        x:=(x mod b+b)mod b;
        writeln(x);
    end.
  • 相关阅读:
    开通博客第一天
    Vue 打包配置productionSourceMap 的记录
    supervisorctl 的 简单记录
    mvn打包方式记录
    springboot日志配置,关于logback
    springboot集成swagger
    关于mapper文件的bean
    elasticsearch 连接、操作记录
    关于前后端分离文件上传的些许问题
    代码优化--策略模式的四种表现
  • 原文地址:https://www.cnblogs.com/WR-Eternity/p/9923543.html
Copyright © 2011-2022 走看看