关于扩展欧几里得算法___基础,基础中的基础
关于扩展欧几里得算法(或者说数论)有点想说的,无关知识,只是自己的一点想法。
本人没有学过数论,也没有学过计算机的数学知识,所以数论实在是让我很头痛的玩意。通常都是避着走,能躲就躲,情愿敲splay也不愿动这东西。不过这东西却实很重要,奉劝各位学noip的IOer们,如果有时间,还是下定决心拼了吧!
就这个扩展欧几里得,我看了后都放了大半年了,还是决心学一下,至少知道它是个什么玩意儿,能干什么!
——————————————————————————————————————
扩展欧几里得可以干三个事(我知道的)
1、ax+by=c的解
1 /求ax+by=c;的一组借 2 3 #include<cstdio> 4 #include<iostream> 5 #include<cstring> 6 7 using namespace std; 8 int a,b,c,x,y,d; 9 int exgcd(int a,int b,int &x,int &y) 10 { 11 if(b==0) 12 { 13 x=1;y=0; 14 return a; 15 } 16 int r=exgcd(b,a%b,y,x); 17 y-=a/b*x; 18 return r; 19 } 20 int main() 21 { 22 cin>>a>>b>>c; 23 d=exgcd(a,b,x,y); 24 if(c%d) 25 { 26 cout<<"no answer!"; 27 return 0; 28 } 29 cout<<"x="<<x*c/d<<endl; 30 cout<<"y="<<y*c/d<<endl; 31 return 0; 32 }
2、ax=b(mod n)的解
1 //求同余方程ax=b(mod n) 2 //相当于求ax+ny=b的解; 3 //求出一个解后,特解注意%n 4 //重要结论:同余方程系中有d(最大公约数)个解,各个解之间差 n/d 5 6 #include<cstdio> 7 #include<iostream> 8 #include<cstring> 9 10 using namespace std; 11 int x,y,a,b,n,d,xx; 12 int exgcd(int a,int b,int &x,int &y) 13 { 14 if(b==0) 15 { 16 x=1;y=0; 17 return a; 18 } 19 int r=exgcd(b,a%b,y,x); 20 y-=a/b*x; 21 return r; 22 } 23 int main() 24 { 25 cin>>a>>b>>n; 26 d=exgcd(a,n,x,y); 27 if(b%d) 28 { 29 cout<<"no answer!"<<endl; 30 return 0; 31 } 32 xx=x*(b/d)%n; 33 for(int i=0;i<d;i++) 34 cout<<(xx+i*(n/d))%n<<endl; 35 return 0; 36 }
3、求解模的逆元
当第二种情况中b=1是得到的唯一解。