一元线性同余方程

定义

a,b是整数,m是正整数,形如a * x ≡ b (mod m),且x是未知数的同余式称为一元线性同余方程。

理论基础与求解

定理1:假设d = gcd(a , m),假设对于整数xx和yy有 d = a * xx + m * yy。若d|b(d能够整出b),那么方程 a * x ≡ b (mod m)有一个解X满足式子 X = xx * (a/b) % m ,其中xx可以用扩展欧几里得算法获得。

扩展欧几里得算法详解见:http://www.cnblogs.com/heweiyou1993/p/3301873.html

 1 long long ExtendedEuclid(long long a,long long b,long long& d,long long& x,long long& y)
 2 {
 3     long long tmp;
 4     if(b == 0)
 5     {
 6         x = 1;
 7         y = 0;
 8         d = a;
 9     }else
10     {
11         ExtendedEuclid(b,a%b,d,x,y);
12         tmp = x;
13         x = y;
14         y = tmp - (a / b) * y;
15     }
16 }

扩展欧几里得源码:

证明1:假设上述成立那么有 a * X ≡ a * xx * (b/d)(mod m),由于a * xx ≡ d (mod m),所以可得到 a * X ≡ d * (b/d)(mod m) ≡ b(mod m)。

定理2:对于a * x ≡ b (mod m),若有解则必有d = gcd( a, m)个解。其解为 res = (X + i * ( b / d)) (mod m),其中X为远同余方程的一个解,i的取值范围为 0 <= i < d。

证明2:若定理2成立则有 a * res (mod m) = a * (X + i * (b / d)) (mod m) = a * X + a* i * (b /d) (mod m) = a * X (mod m) = b。

源代码如下:

 

 1 void RemainderEquation(long long a,long long b,long long m)
 2 {
 3     long long X,Y,d;
 4     long long res;
 5     ExtendedEuclid(a,m,d,X,Y);
 6 
 7     if(b%d == 0)
 8     {
 9         X = X * (b / d) % m;//得到同于方程一解
10         for(int i = 0 ; i < d; i++)
11         {
12             res = (X + (i * (b/d))) % m;
13             printf("%lld\n",res);
14         }
15     }else
16     {
17         printf("No Sulutions!\n");
18     }
19 }

最小正整数解

由于一元线性同余方程的通解可以写成res = ( X + i * (b /d) )  (mod m) = X + i * (m/d) + m * y,由于 y 与 i 均为变量因此可以将其合并得到式子 res = X + y * ( m/d)   (其中将原式中的 m * y 看做 m/d  * d * y,由于y是变量因此可以将 d*y这个整体看为 y),因此可以得到res = X(mod m/d) ,设m/d 为 t ,其最小正整数解可表示为 (X%t + t) % t。

 

posted @ 2013-09-04 19:59  Howey  阅读(2587)  评论(0编辑  收藏  举报