• 线性同余系列


                                                  线形同余方程系列

       求解形如 :  ax ≡ b (mod n)

       方程可以变形为 : ax – ny = b; 对于这个方程的求解可以使用扩展欧几里得定理做,有解的首要条件便是gcd(a ,n) 能够整除b ; 证明如下: 如果(a ,n) 不能够整除b ,那么方程两边同除以(a ,n),有 a’x – n’y = b/(a ,n) ; 可以看出,方程左边肯定是整数,右边却为小数,所以(a ,n) 肯定能够整除b ;

       对于方程: ax – ny = gcd(a ,n);通过扩展欧几里得可以求出方程的某个解: 假设求得x0,那么方程其余解可以表示为 : x0 + k* n/(a ,n); k∈Z(对于这个通解,我参考很多网上的资料,可是说得都不是很清楚,智商不高的我表示我研究两天才有所领悟) ; 首先,由于y=ax/n; (这里的除法是计算机语言中的除法) 也就是说随着 x 的变化,y是可以相应变化。。 那么,x0满足条件 ,x1=x0+n也满足条件,对应y1=y0+a; 但我们可以缩小这个间距,那么是不是y1=y0+1;满足条件呢?此时的x1=x0+n/a; 但由于求的是整数解,我们无法保证n/a 是一个整数。那么也就是说我们要找的就是t ∈ [1,n],使得n/t是个整数且t最大,当然同时还要满足a*n/t % n==0;

    那么就有a/t *n % n ==0; 也就是 a / t 也得是一个整数,那么能够被a、n整除的最大t便是 gcd(a ,n);所以 通解为 xk= x0 + k*n/(a ,n); k∈Z; (为啥总觉得自己把一个很简单的问题想得太复杂呢。。。因为通过这个式子:  ,可以很容易看出 通解的间距为: n’; 66666... )

     现在来看线性同余方程组:

       解决形如:  x ≡ b1 (mod a1);  ①

                   x ≡ b2 (mod a2);  ②

                     x ≡ bi (mod ai);

       解决方法是两两一对求解,然后再通过得到的解构造一个新的方程,然后递推求解。

       首先: 由 ①、② 得 a1 * k1 – a2 * k2 = b2 - b1; ③

       那么方程组有解的首要条件便是 gcd(a1,a2) | (b2-b1);如果不满足这个条件,方程无解。

    式子 a1 * k1 – a2 * k2 = gcd(a1,a2);通过扩展欧几里得定理可以求出某个解k1, 那么式子 ③ 中的k1=k1*(b2-b1)/(a1,a2);

     由于要让k1 尽量小,且为正整数 ; 令 t= a2/(a1,a2); 那么有k1=(k1 % t + t ) % t; (t 的由来参看上部分)

       现在可以明了方程组的解为 x = a1 * k1 + b1; ④

       那么可以构造出第三个式子 : b1 = x; a1= lcm[a1,a2];

       关于构造第三个式子的理解: 如果只有两个方程式子,那么现在得出的解x便是满足条件的最小解x,但如果还有第三或者更多的线性同余方程,那么如果最后的解x’大于x,那么他必然满足 x’% lcm[a1,a2] == x; 即 x’就是 ④ 的通解 。

    如果说上面的理解还有需要想象的地方(0.0 我反正找不到...),那么下面我给出比较严谨的公式推导过程:

       x ≡ b1 (mod a1);  ①

     x ≡ b2 (mod a2);  ②

       由 ① 得 x = a1*k1+b1; ③

       将 ③ 代入 ② :有 a1*k1+b1 ≡ b2 (mod a2) ;

     --> a1*k1 ≡ b2-b1 (mod a2); ④

     令 d= gcd(a1,a2);   B= b2-b1;

     由 ④ 有: a1*k1 = k2*a2+B;

     --> a1*k1/d = k2*a2/d + B/d ;

     令B’= B/d;

     有 a1*k1/d = k2*a2/d + B’; ⑤

     由 ⑤ 得: a1*k1/d ≡ B’(mod a2/d);

     --> k1 ≡ K (mod a2/d);

     --> k1 = k’*a2/d + K; ⑥ 

     将 ⑥ 代入 ③ :

     x = (k’*a2/d + K)*a1+b1;

     --> x = k’*a1*a2/d +K*a1 +b1;

     --> x ≡ K*a1 +b1 (mod a1*a2/d); ⑦

     由 ⑦ 也验证了构造出来的新方程的a’= a1 * a2 / d ; b’= K * a1 + b1 ;

       上面讨论的是方程组x前面没有系数的情况,但如果前面存在系数w1,做法也几乎一样,就是先两边同除以gcd(wi,ai);得到式子:wi’* x ≡ bi’(mod ai’),然后此时可求wi'关于ai'的逆元e,最后化得x≡bi'*e (mod ai')的形式,比如3x ≡ 2 (mod 5) ; 3、5 的公约数是1 ,所以第一步已经完成,现在3、5的逆元为2(即满足3*2 ≡ 1 (mod 5) )所以式子变成 x ≡ 4 (mod 5);

       以上的解法是通用于这类型题的,如果题目中多一个限制条件:强调a1、a2、…、ak是互质的,那么可以用中国剩余定理来解,解法如下:

       从刚才通用的解法中,我们也可以看出最后的解范围为0<=x<=lcm[a1,a2,…,ak],如果a1、a2等是互质的话,设他们的最小公倍数为M,M=a1*a2*…*ak;记Mi=M/ai;那么必然存在整数解p,q使得Mi*pi+ai*qi=1;(因为gcd(Mi,ai)==1,这个就不用我解释吧),记ei=Mi*pi;那么有:

    ei ≡ 0 (mod aj) ;  j!=i;  这个比较好理解吧,Mj中包括着ai;

    ei ≡ 1 (mod aj) ;  j==i; Mj中不包括ai;

    所以可以很容易得出,线性同余方程组的通解为 x = e1*b1+e2*b2+ ...+ek*bk ; 这个就是单纯地从定义得到, 比如 :e1 % a1 = 1 ; 那么 e1 * b1 % a1 =b1; 而其他项取余 a1 都等于0,所以得出的这个式子肯定满足上面那k个线性同余方程,当然,如果想要最小正整数解,可以通过加减M来得到。这个适用于a1、a2、…、ak互质的情况。

       ……以上就是解决线性同余方程组的方法了。

       给一道模板题: http://acm.fzu.edu.cn/problem.php?pid=1402

     

     1 #include<stdio.h>
     2 typedef long long LL;
     3 void exGcd(LL a,LL b,LL &d,LL &x,LL &y)
     4 {
     5   if(b==0)
     6   {
     7     d=a;
     8     x=1;
     9     y=0;
    10   }
    11   else
    12   {
    13     exGcd(b,a%b,d,x,y);
    14     int t=x;
    15     x=y;
    16     y=t-a/b*y;
    17   }
    18 }
    19 int main()
    20 {
    21   LL n,a1,a2,b1,b2;
    22   LL x,y,d,ans;
    23   while(scanf("%I64d",&n)!=EOF)
    24   {
    25     ans=1;
    26     scanf("%I64d%I64d",&a1,&b1);
    27     for(LL i=1;i<n;i++)
    28     {
    29       scanf("%I64d%I64d",&a2,&b2);
    30       exGcd(a1,a2,d,x,y);
    31       if((b2-b1)%d!=0)
    32       {
    33         ans=0;
    34       }
    35       LL t=a2/d;
    36       x=(x*(b2-b1)/d%t+t)%t;
    37       b1=a1*x+b1;
    38       a1=a1*a2/d;
    39     }
    40     if(ans!=0)
    41       printf("%I64d
    ",b1);
    42   }
    43   return 0;
    44 }
  • 相关阅读:
    WPF控件操作之改变父控件之TabControl示例
    WPF里面的DockPanel的Fill去哪了,如何填满整个空间
    [原创]winform自定义控件之类属性-多重属性-可折叠属性
    WinForm之DataBinding
    WinForm自定义控件之DefaultValue的误解
    code snippet:依赖属性propa的小技巧
    【原创】WinForm中实现单独Time控件的方式
    node.js安装本地模块遇到的目录锁定问题【新手问题】
    《程序员思维修炼》之德雷福斯模型
    IOptions、IOptionsMonitor以及IOptionsSnapshot
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/4714512.html
Copyright © 2020-2023  润新知