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

    题目 给定两个整数 \(a,c,m\) 请求出模方程

    \[ax\equiv c\pmod m\tag{1} \]

    的最小正整数解。

    分析 我们构造方程

    \[ax\equiv 1\pmod m\tag{2} \]

    不难发现,如果我们能求出 \((2)\) 中的一个解,将其乘上 \(c\) 即可得到 \((1)\) 的一个解。那么现在就要求 \((2)\) 的一个解。其等价于不定方程

    \[ax+my=1\tag{3} \]

    我们构造

    \[mx+(a\%m)y=1\tag{4} \]

    它等价于

    \[mx+(a-a/m\cdot m)y=1\tag{5} \]

    其中"/"是整除。

    不难发现,如果我们知道 \((5)\) 的一个解 \(x_0,y_0\),则有\(y_0,x_0-a/m\cdot y\)\((3)\) 的一个解,其中"/"是整除。边界条件为 \(m=0\)\(x=1,y=0\),所以可以递归求解。

    假定我们知道了 \((2)\)(也即\((3)\))的一组解 \(x_0,y_0\)\(c\cdot x_0\)\((1)\) 的一个解,所以 \(c\cdot x_0\%\frac{m}{GCD(a,m)}\)\((1)\) 的最小正整数解(为什么?)。

    例题 青蛙的约会

    分析 即求

    \[x+k\cdot m \equiv y + k\cdot n \pmod l \]

    的最小正整数解。

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    ll x, y, m, n, l;
    
    ll exgcd(ll a, ll b, ll& x, ll& y)
    {
        if (!b) return x = 1, y = 0, a;
        
        ll d = exgcd(b, a % b, y, x);
        return y -= a / b * x, d;
    }
    
    int main()
    {
        while (~scanf("%lld%lld%lld%lld%lld", &x, &y, &m, &n, &l)) {
            if (n < m) swap(n, m), swap(x, y);
    
            ll X = 0, Y = 0;
            ll d = exgcd(n - m, l, X, Y), r = l / d;
    
            if ((x - y) % d) puts("Impossible");
            else printf("%lld\n", ((x - y) / d * X % r + r) % r);
        }
    }
    
  • 相关阅读:
    mysql 远程连接数据库的二种方法
    安装mysql-5.7.12-winx64
    快速提升word文档编写质量
    查看linux系统版本命令汇总
    SpringMVC+mybatis+maven+Ehcache缓存实现
    linux下的java开发环境
    appium 常用api介绍(2)
    appium 常用api介绍(1)
    appium入门
    Mysql5.7服务下载安装
  • 原文地址:https://www.cnblogs.com/whx1003/p/11716609.html
Copyright © 2011-2022 走看看