扩展欧几里德
来源:互联网 发布:淘宝手机端发布详情页 编辑:程序博客网 时间:2024/06/03 20:55
欧几里德
int gcd(int a,int b){
if(b) while(b^=a^=b^=a%=b);
return a;
}
扩展欧几里德
int ext_gcd(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int ans=ext_gcd(b,a%b,y,x);
y-=(a/b)*x; // x=y` y=x`-[a/b]*y`
return ans;
}
求得ax+by=gcd
若x+=k*(b/gcd) y-=k*(a/gcd),等式一样成立
二进制gcd算法:
如果a和b都是偶数,则gcd(a,b)=2*gcd(a/2,b/2)
如果a是奇数,b是偶数,则gcd(a,b)=gcd(a,b/2)
如果a和b都是奇数,则gcd=(b,(a-b)/2)
例题: HDOJ 1576
题目:
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
做法:
根据题目我们知道: n=A%9973=A-A/9973*9973。设A/B=x,则A=Bx。所以Bx-A/9973*9973=n。
即Bx-9973y=n ---① (y是多少不重要也不用管 ,用不上)
题目所求的值就是x%9973的值
利用扩展欧几里德算法可求出gcd(B,9973)=Bx1+9973y1=1 的x1,x=n*x1(等式两边乘于n就是①式了嘛)
为什么可以这样做:①式有无数解,最原始的解就是x0 = x1* n/ gcd(B,9973)
其他解可通过x=x0+t*9973, y=y0-t*B(t为整数)得来!!
得到的x可能为负值,所以还需要x=(x%9973+9973)%9973。(x=abs(x)%9973是错的)
怕不同编译器对余数的符号取法不一样出错,就用
if(x<0) x=x+(-x/9973+1)*9973;
else x=x%9973;
1 0
- 欧几里德和扩展欧几里德
- 欧几里德, 与 扩展欧几里德
- 欧几里德|扩展欧几里德
- 欧几里德&&扩展欧几里德详解
- 欧几里德&&扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德!!!!!
- 扩展欧几里德
- 扩展欧几里德
- 扩展欧几里德
- UVA 12219 Common Subexpression Elimination(表达式树)
- POJ 2406
- 启动Android系统照相机
- 机器学习(二):线性回归
- LRU缓存介绍与实现 (Java)
- 扩展欧几里德
- HTML5-----学习笔记1
- Linux下gitblit的安装和配置
- Oracle 11G R2 用exp无法导出空表解决方法
- [leetcode]113. Path Sum II -- JavaScript 代码
- 多线程编程学习(001)
- Spark SQL
- mdev的使用以及mdev.conf的规则配置--busybox
- WebService Xml 字符串形式传值