*d|a且d|b =>d|(ax+by). * gcd(a,b)=gcd(b,a%b). 设d=gcd(a,b),则d|a且d|b,则d|ax+by.又a%b=a-(a/b)*b,所以d|(a%b)->d=gcd(b,a%b). 所以可以得出欧几里德算法,也就是辗转相除法:
GCD int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); }
*基于以下事实:gcd(a,b)=gcd(b,a%b). 可以得出:存在x,y,x',y'使得: ax+by=d (1) bx'+(a%b)y'=d 即 bx'+[a-(a/b)*b]y'=d 整理得:ay'+b(x'-(a/b)y')=d (2) 由(1)(2)得:x=y' y=x'-(a/b)y' 当b=0时,ax=gcd(a,0)=a,得x=1. 可以得到扩展欧几里德算法:
EXTEND-EUCLID int Extend_Euclid(int a,int b,int & x,int &y) { if(b==0) { x=1; y=0; return a; } else { int gcd,t; gcd=Extend_Euclid(b,a%b,x,y); t=x; x=y; y=t-(a/b)*y; return gcd; } }
*应用扩展欧几里德算法可以求二元一次方程的整数解 对方程:ax+by=c 设d=gcd(a,b), a'=a/d, b'=b/d,则方程变形为d(a'x+b'y)=c 若方程有整数解,则d|c,否则无解. 设c'=c/d,则方程ax+by=c等价于a'x+b'y=c' 因为gcd(a',b')=1,则我们可以求得a'x+b'y=gcd(a',b')=1的解,即ax+by=gcd(a,b)=d的解x,y。 则c'x,c'y就是ax+by=c的一组解。 xx=c'x+b't, yy=c'y-a't t∈Z就是所有满足条件的解。
*对于求解模线性方程ax≡b(modn),假设对整数x',y',有d=ax'+ny',则方程ax≡b(modn)有一个解的值为x0,满足x0=x'*(b/d)modn. ax0≡ax'(b/d) (mod n) ≡d(b/d) (mod n) ≡b (mod n)
Modular_Linear int Modular_Linear(int a,int b,int n)//ax=b(mod n) { int d,x,y,x0,i; d=Extend_Euclid(a,n,x,y); if(b%d==0) { x0=(x*(b/d))%n; if(x0<n) x0+=n; for(i=0;i<d;i++) cout<<(x0+i*n/d)%n<<endl; } return 0; }
|