zoukankan      html  css  js  c++  java
  • 洛谷 P1082 同余方程

    源代码
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<cstring>
    using namespace std;

    long
    long x, y;//目前方程真正的解 void exgcd(long long a, long long b) { //当前目的:求解 ax + by = gcd(a, b) 这么一个方程 if(b == 0) //a, b不断改变的过程中,b最终必然会成为0 {
    x = 1;//当 b=0 时,方程若要成立,则只需令 x=1,y=0 y = 0; return; } exgcd(b, a % b);//把下一层系数传进去(先求下一个方程的解 ) //现在我们已经拿到了下一个方程的解x, y long long tx = x;//暂时存一下x,别丢了 x = y; y = tx - a / b * y; } int main() { long long a, b; cin >> a >> b; exgcd(a, b); x = (x % b + b) % b;//我们求出来的x必然满足方程,但不一定是最小正整数解,所以要进行答案处理 printf("%lld ", x); return 0; }

    这一道题是zhx大佬上课布置下的数论题,求 ax mod b =1 的最小正整数解 x,就要用到扩展欧几里得来求解。

    但作为一名蒟蒻,还是有所借鉴:https://www.luogu.com.cn/blog/cicos/solution-p1082  %%%orz

     


    进入正题!

    1.首先,若要求 ax mod b = 1 的最小正整数解 x,即为求解不定方程:ax+by=1 ;(注:扩展欧几里得算法可以适用于所有的 ax + by = gcd(a ,b)的不定方程)

       原理为:不定方程 ax + by =m 有解的必要条件是:m mod gcd( a ,b )= 0

       证明:因为 a 为 gcd( a ,b )的倍数,b 也为 gcd( a ,b )的倍数

               又因为 a,b 均为整数,所以 ax + by 也是 gcd( a ,b )的倍数

               而 m = ax + by ,那么 m 就是 gcd( a ,b )的倍数, 故 m mod gcd( a ,b )= 0  

    ax + by = m

    2. 设 gcd( a ,b )= n ,求 ax + by = n , 可以假设,如果我们事先拥有一组解 p,q,使得 bp + ( a mod b)q = n ;

                那么就一定会有:ax + by = bp +( a mod b )q 

                当这一假设成立时,我们就可以将目标转化为:求出上述式子中能够满足的 x,y ;此时,我们就可以通过求出一组解来推得 x 的最小正整数解

    3. 取模运算的实质:a mod b = a - b *( a / b ) ,则上述的等式可进行转化。

        即为:bp +( a mod b )q  = b*p + ( a - b *( a / b ))*q = b*p + a*q - b *( a / b )* q = a * q + b * ( p -( a / b )* q )

        此时,我们可以看出,满足不定方程的一组解就是 :x = q ,y = p -( a / b )* q;

        那么,我们就需要进一步地,尽可能地将这一假设满足,就需要再求出 p 和 q

        但是,为了要求出 p ,q ,我们又可以写出新的不定方程来尽可能地求出 p 和 q ,而过程就和上述的 1 ,2 ,3  一样,在不断地循环,寻找着能够支持上一组数据的解

        这便形成了一种递归

    4.递归需要设立终止条件,而在这个过程中,a 会被不断地替换成为 b , 而 b 会被不断地替换为 a mod b (和辗转相除法一样)

        最后,我们会得到 an = n ,bn = 0 ;

        那么把它回代,即得:an * x + bn * y = n * x + 0 * y = n ;

        那么,只要当 x = 1 时,等式即可成立 ,那么只要将其继续回代,就能求出最终的一组答案(并不一定是最小正整数解)

    总结一下,扩展欧几里得算法和辗转相除法类似,也都是递归,就是在有限的递归过程中缩小系数,确定最后一组解。

    最后,只要将答案 x 化为一个最小正整数即可。

        

  • 相关阅读:
    HTML5侧滑聊天面板
    HTML5世界地图
    BZOJ_1042_[HAOI2008]硬币购物_容斥原理+背包
    BZOJ_1342_[Baltic2007]Sound静音问题_单调队列
    BZOJ_2343_[Usaco2011 Open]修剪草坪 _单调队列_DP
    BZOJ_2595_[Wc2008]游览计划_斯坦纳树
    BZOJ_5180_[Baltic2016]Cities_ 斯坦纳树
    BZOJ_4006_[JLOI2015]管道连接_斯坦纳树
    51nod_1412_AVL树的种类_动态规划
    BZOJ_3143_[Hnoi2013]游走_期望DP+高斯消元
  • 原文地址:https://www.cnblogs.com/jd1412/p/12709042.html
Copyright © 2011-2022 走看看