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

    贝祖定理 如果 (a,b) 是整数,那么一定存在整数 (x,y) 使得 (ax+by=gcd(a,b))

    判断有解性 如果 (ax+by=m) 有解,那么 (m) 一定是 (gcd(a,b)) 的若干倍。如果 (ax+by=1) 有解,那么 (gcd(a,b)=1)

    辗转相除法求 (gcd)

    int gcd(int a, int b){
        return b == 0 ? a : gcd(b, a % b);
    }
    

    扩展欧几里得求解

    对于方程 (ax+by=gcd(a,b)) ,我们有:

    [egin{split} ax_1+by_1 &= gcd(a,b) \ bx_2+(a\%b)y_2 &= gcd(b,a\%b) end{split}]

    两式均满足贝祖定理,且一定存在解。

    我们将 ((a\%b)) 换成 ((a - lfloor frac{a}{b} floor cdot b)) 有:

    [bx_2+(a - lfloor frac{a}{b} floor cdot b)y_2 = gcd(b,a\%b) ]

    由于 (gcd(a,b)=gcd(b,a\%b)) ,联立两式得:

    [egin{split} x_1 &= y_2 \ y_1 &= x_2 - lfloor frac{a}{b} floorcdot y_2 end{split}]

    易得,边界条件为:

    [gcd(a,0)=a \ ax_0+by_0=a Rightarrow x_0 =1;y_0=0 ]

    扩展欧几里得的通解

    (x_c,y_c) 为算法求出的一组解,那么方程的通解为:

    [egin{split} x &= x_c + k cdot frac{b}{gcd(a,b)} \ y &= y_c - k cdot frac{a}{gcd(a,b)} end{split}]

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    
    using namespace std;
    
    int exgcd(int a,int b,int &x,int &y)
    {
        if(b == 0){
            x = 1; y = 0;
            return a;
        }
        int r = exgcd(b, a % b, x, y);
        int temp = y;
        y = x - (a / b) * y;
        x = temp;
        return r;
    }
    int main()
    {
        int a, b;
        cin >> a >> b;
        int x, y;
        int d = exgcd(a, b, x, y);
        cout << x << " " << y << " " << d << endl;
        return 0;
    }
    
  • 相关阅读:
    ruby 中 raise 抛出异常
    ruby中attr_accessor方法的理解
    Redis实现分布式缓存
    应用服务器集群概念
    反向代理和正向代理区别
    如何限制同一用户同时登录多台设备?
    Docker 初始
    Java 的反射机制你了解多少?
    JWT 实战
    判断 uniapp 项目运行到 什么机型
  • 原文地址:https://www.cnblogs.com/solvit/p/11432724.html
Copyright © 2011-2022 走看看