欧几里德再现(模板-不完全转载!)
本文借鉴于 :http://blog.csdn.net/u013451221/article/details/38497029
内容略微不同。
1.1.欧几里得(最大公约数,最小公倍数)
int gcd(int a,int b) { if((b==0) return a; else gcd(b,a%b); }
2扩展欧几里德求最小整数解;
给出 a*x+b*y=c
void exgcd(ll a,ll b,ll &d,ll &x,ll &y) { if (!b) { d=a; x=1; y=0; } else { exgcd(b,a%b,d,y,x); y-=x*(a/b); } }
代码求解的是a*x+b*y=gcd(a,b);
if(c%gcd(a,b)==0) 说明有解;
且最小整数解为 b=b/gcd(a,b);x=x*(c/gcd(a,b));x=(x%b+b)%b;
3.最小乘法逆元
类似于求最小正整数解,只不过最后要 a*x+b*y=1;
什么是乘法逆元:
例如:4关于 1模7的乘法逆元为多少?
4x = 1 mod 7;
此方程等价于求解:
4x=7k+1;
其中x和K都是整数。
若ax=1 mod f,则称a关于模f的乘法逆元为x,可表示为 ax=1(mod f);
int cal(int a,int m) { int x,y; int gcd=e_gcd(a,m,x,y); if(1%gcd!=0) return -1; x*=1/gcd; m=abs(m); int ans=x%m; if(ans<=0) ans+=m; return ans; }