求解模线性方程

  模和同余

定义:设abm均为整数,且m>0。如果abm除所得的余数相同,那么称ab关于模m是同余的,记作aº b mod n.

同于有以下性质:

1.         n|(a-b),aºb mod n

2.         a mod nºb mod n,则aºb mod n

3.         aºa mod n

4.         aºb mod n,则bºa mod n

5.         aºb mod nbºc mod n,则aºc mod n

6.         aºb mod ccºd mod n,则a+cºb+d mod n.

一般的,定义zn为小于n的所有非负整数集合,即Zn=0,1,……,n-1},称Zn为模n的同余类集合。Zn中的加法和乘法都为模n运算,具有如下性质:

1.     交换率 (w+x)mod n º (x+w)mod n

 (w*x)mod nº (x*w)mod n

2.     结合律  [(w+x)+y]mod nº [w+(x+y)]mod n

  [(w*x)*y]mod nº [w*(x*y)]mod n

3.     分配率  [w*(x+y)]mod nº [(w*x)+(w*y)]mod n

4.     单位元  (0+w)mod nºw mod n

 (1*w)mod nºw mod n

5.     加法逆元: w属于Zn,存在x属于Zn,使得w+x=0 mod n,称xw的加法逆元,记作x=-w

6.     乘法逆元 : w属于Zn,如果存在x属于Zn,使得w*x=1modn,就说w是可逆的,称xw的乘法逆元,记作x=w

并不是每个元素都又乘法逆元,可以证明,w属于Zn是可逆的,当且仅当gcdwn=1.如果w是可逆的,则可顶一除法。

 

费马小定理:设ap为整数,且p为素数,pp,a=1,

那么:a^(p-1) º1(mod p).

    例:当a分别为35时,求a^1617除后所得的余数。

答案:均为1.

 

模线性方程      

                                  axºb(mod m)

 

      其中a,bm是已知的(m>0),要求解出满足上式的对模mx值。满足同余方程的x可能有多个,也可能一个都没有,上述模线性方程也称为一次同余方程。

     例如:57xº7mod 11)有一个解x=9,而9xº7mod 6)无解。

     解:模线性方程axºbmod )的步骤如下:

(1) d=gcda,m

(2)d不是b的因数,则axºb(mod m)无解,结束;否则转(3

(3)x0,y0,a*x0+m*y0=d;

(4)由于db的因数,将a*x0+m*y0=d改写,得a(x0*(b/d))+m*(y0*(b/d))=b, 

      于是ax+my=b的一个特解为 x=x0*(b/d),y=y0*(b/d);

(5)x0*(b/d)axºmod m)的一个特解,由此的axºb(mod m)的所有解

    (共d个)为:x= (x0*(b/d)+ i*(m/d) ) (mod m),    i=0,1,2,3,4.……d-1

定理1

      d=gcd(a,n),假定对整数xy满足d=ax+by(比如用扩展Euclid算法求出的一组解)。如果d | b,则方程ax=b(modn)有一个解x0满足x0=x*(b/d) mod n 。特别的设e=x0+n,方程ax=b(mod n)的最小整数解x1=e mod(n/d),最大整数解x2=x1+(d-1)*(n/d)
定理2

       假设方程ax=b(mod n)有解,且x0是方程的任意一个解,则该方程对模n恰有d个不同的解(d=gcd(a,n)),分别为:xi=x0+i*(n/d) mod n

long long exgcd(long long a, long long b, long long &x,long long &y)

{

    if (b == 0)

    {

        x = 1, y = 0;

        return a;

    }

    long long re = exgcd(b, a % b, x ,y);

    long long tmp = x;

    x = y;

    y = tmp - a / b * y;

    return re;

}

long long modular_linear(long long a,long long b,long long n)

{

    long long x,y;

    long long d = exgcd(a,n,x,y);

    if (b % d)

    {

        return -1;

    }

    long long re = x*(b/d) %n + n;

    re = re%(n /d);

    return re;

}

用扩展欧几里德解模线性方程ax=b mod n

bool modularLinearEquation(int a,int b,int n)

{

int x,y,x0,i;

int d=extend_gcd(a,n,x,y);

if(b%d)

return false;

x0=x*(b/d)%n;

for(i=1;i<d;i++)

{

printf("%d\n",(x0+i*(n/d))%n);

}

return true;

}

posted on 2011-08-27 17:40  pcoda  阅读(639)  评论(0编辑  收藏  举报