扩展欧几里得+逆元
2016-10-05 17:06
363 查看
【传送门】参考了几位大神的资料,本蒟蒻表示不胜感激
http://chhaj5236.blog.163.com/blog/static/112881081200942542255916/(真心膜拜)
http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
http://blog.sina.com.cn/s/blog_7064e7850100yeu1.html
【扩欧的求法】经典的欧几里得算法早就烂熟于心,但是对于扩欧我原来一无所知。扩展欧几里德主要是用来与求解线性方程相关的问题。现在假设一个方程为a*x+b*y=m,如果这个线性方程有解,那么一定有gcd(a,b)
| m,即a,b的最大公约数能够整除m(m%gcd(a,b)==0)。
{证明}很简单,由于a%gcd(a,b)==b%gcd(a,b)==0,所以a*x+b*y肯定能够整除gcd(a,b)。
那么以下是关于此方程的解法:
令a1=a/gcd(a,b),b1=b/gcd(a,b),P=m/gcd(a,b)。如果我们能够首先求出满足a*x1+b*y1=gcd(a,b)(即原式两边除以P)这个方程的x1和y1,那么x=x1*P,y=y1*P就可以求出来了。由欧几里德算法gcd(a,b)=gcd(b,a%b),所以a*x1+b*y1=gcd(a,b)=gcd(b,a%b)=b*x2+(a%b)*y2,现在只要做一些变形就可以得到扩展欧几里德算法中的用到的式子了。令k=a/b(商),r=a%b(余数),那么a=k*b+r。所以r=a-k*b,带入上式,得到a*x1+b*y1=b*x2+(a-(a/b)*b)y2=a*y2+b*(x2-(a/b)*y2) => x1=y2,y1=x2-(a/b)*y2。有了这两个式子我们就知道了在用欧几里德求最大公约数的时候,相应的参数x,y的变化。现在再回过头来看一下扩展欧几里德算法的代码就很好理解了,实际上扩展欧几里德就是在求a和b的最大公约数的同时,也将满足方程a*x1+b*y1=gcd(a,b)的一组x1和y1的值求了出来。
【代码】
int exGcd(int a,int b,int &x,int &y)
{
if(b==0){x=1;y=0;return a;}
int g=exGcd(b,a%b,x,y);
int temp=x;x=y;
y=temp-(a/b)*y;
return g;
}
最后再乘上P,你懂的。这就是一组解。
【逆元】设我们要求a/b%p的值,我们可以转化为a*x%p。显然,(1/b)%p=x%p,x*b%p=1。
前提:gcd(x,b)=1.这样的话,x就存在。
如何求解a*x%n=1的方程呢?我们可以化成ax+ny=1,然后在上述gcd中带出。
【疑问】为什么网上的逆元模板都是有3个x和y的。= =
http://chhaj5236.blog.163.com/blog/static/112881081200942542255916/(真心膜拜)
http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
http://blog.sina.com.cn/s/blog_7064e7850100yeu1.html
【扩欧的求法】经典的欧几里得算法早就烂熟于心,但是对于扩欧我原来一无所知。扩展欧几里德主要是用来与求解线性方程相关的问题。现在假设一个方程为a*x+b*y=m,如果这个线性方程有解,那么一定有gcd(a,b)
| m,即a,b的最大公约数能够整除m(m%gcd(a,b)==0)。
{证明}很简单,由于a%gcd(a,b)==b%gcd(a,b)==0,所以a*x+b*y肯定能够整除gcd(a,b)。
那么以下是关于此方程的解法:
令a1=a/gcd(a,b),b1=b/gcd(a,b),P=m/gcd(a,b)。如果我们能够首先求出满足a*x1+b*y1=gcd(a,b)(即原式两边除以P)这个方程的x1和y1,那么x=x1*P,y=y1*P就可以求出来了。由欧几里德算法gcd(a,b)=gcd(b,a%b),所以a*x1+b*y1=gcd(a,b)=gcd(b,a%b)=b*x2+(a%b)*y2,现在只要做一些变形就可以得到扩展欧几里德算法中的用到的式子了。令k=a/b(商),r=a%b(余数),那么a=k*b+r。所以r=a-k*b,带入上式,得到a*x1+b*y1=b*x2+(a-(a/b)*b)y2=a*y2+b*(x2-(a/b)*y2) => x1=y2,y1=x2-(a/b)*y2。有了这两个式子我们就知道了在用欧几里德求最大公约数的时候,相应的参数x,y的变化。现在再回过头来看一下扩展欧几里德算法的代码就很好理解了,实际上扩展欧几里德就是在求a和b的最大公约数的同时,也将满足方程a*x1+b*y1=gcd(a,b)的一组x1和y1的值求了出来。
【代码】
int exGcd(int a,int b,int &x,int &y)
{
if(b==0){x=1;y=0;return a;}
int g=exGcd(b,a%b,x,y);
int temp=x;x=y;
y=temp-(a/b)*y;
return g;
}
最后再乘上P,你懂的。这就是一组解。
【逆元】设我们要求a/b%p的值,我们可以转化为a*x%p。显然,(1/b)%p=x%p,x*b%p=1。
前提:gcd(x,b)=1.这样的话,x就存在。
如何求解a*x%n=1的方程呢?我们可以化成ax+ny=1,然后在上述gcd中带出。
【疑问】为什么网上的逆元模板都是有3个x和y的。= =
相关文章推荐
- 逆元的几种求法(扩展欧几里得,费马小定理或欧拉定理,特例,打表等)
- ZOJ 3609 Modular Inverse(扩展欧几里得求逆元)
- UESTC 1712 Easy Problem With Numbers 线段树+扩展欧几里得求逆元
- 扩展欧几里得(求逆元)
- 中国剩余定理+扩展欧几里得求逆元 hdu 1006
- 扩展欧几里得与逆元
- 扩展欧几里得,逆元初识(poj 1061+codeforce 7C line+hdu 1576 A/B)
- HDOJ A/B 1576【扩展欧几里得+求逆元】
- hdoj 1576 A/B [扩展欧几里得.逆元]
- 【数学/扩展欧几里得/线性求逆元】[Sdoi2008]沙拉公主的困惑
- nyist 769 乘数密码(扩展欧几里得求逆元)
- HUD 1576 A/B【逆元 -> 扩展欧几里得】
- 扩展欧几里得-逆元 浙江2012年省赛J题 Modular Inverse
- BZOJ1951 [Sdoi2010]古代猪文 【费马小定理 + Lucas定理 + 中国剩余定理 + 逆元递推 + 扩展欧几里得】
- 数论-hdu-1576-A/B-逆元-扩展欧几里得
- HDU 1576 A/B (扩展欧几里得求逆元)
- 数论 —— 逆元(费马小定理/扩展欧几里得)
- csu1163扩展欧几里得之乘法逆元
- 数论基础(欧几里得,扩展欧几里得,逆元,斯特林)
- 【数学/扩展欧几里得/线性求逆元】[Sdoi2008]沙拉公主的困惑