gcd模板(欧几里得与扩展欧几里得、拓展欧几里得求逆元)
gcd(欧几里得算法辗转相除法):
gcd ( a , b )= d ;
即 d = gcd ( a , b ) = gcd ( b , a mod b );以此式进行递归即可。
之前一直愚蠢地以为辗转相除法输进去时 a 要大于 b ,现在发现事实上如果 a 小于 b,那第一次就会先交换 a 与 b。
#include<stdio.h>
#define ll long long ll gcd(ll a,ll b){
return b==?a:gcd(b,a%b);
} int main(){
ll a,b;
while(scanf("%lld%lld",&a,&b)!=EOF){
printf("%lld\n",gcd(a,b));
// printf("%lld\n",a>b?gcd(a,b):gcd(b,a));
}
return ;
}
在原基础上改成循环之后的GCD:
ll gcd(ll a,ll b){
for(;a>&&b>;a>b?a%=b:b%=a);
return a+b;
}
这个代码是针对非负数范围的,但除此之外我还纠结了很久,在非负数的范围内(long long内)与普通递归的gcd对拍并没有发现问题,一直做题的时候也没有发现有什么问题,但是刷到一题UVA10325,经测试数据中没有给0或负数,但是用这个WA用递归版的AC,并不知道为什么。
所以……还是库函数/递归保平安吧
拓展欧几里得:
当 gcd ( a , b )= d 时,求绝对值和最小的 x , y 使得 x * a + y * b = d ;
d = gcd ( a , b ) = gcd ( b , a mod b );
设:
x1 * a + y1 * b = d ; ①
x2 * b + y2 * ( a mod b ) = d ; ②
因为 a mod b = a - ( a / b )* b; ③(除法为整除)
将③代入①整理得:
y2 * a + ( x2 - ( a / b ) * y2 ) * b = d; ④
由①和④整理得:
x1 = y2 ;
y1 = x2 - ( a / b ) * y2;
将此结论代入递归函数既得。
#include<stdio.h>
#define ll long long void gcd(ll a,ll b,ll& d,ll& x,ll& y){
if(!b){d=a;x=;y=;}
else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
} int main(){
ll a,b,d,x,y;
while(scanf("%lld%lld",&a,&b)!=EOF){
gcd(a,b,d,x,y);
printf("%lld*%lld+%lld*%lld=%lld\n",a,x,b,y,d);
}
return ;
}
拓展欧几里得求逆元:
当 a 与 b 互素时有 gcd ( a , b ) = 1 ;
即得: a * x + b * y = 1;
a * x ≡ 1 ( mod b );
由于 a 与 b 互素,同余式两边可以同除 a ,得:
1 * x ≡ 1 / a (mod b);
因此 x 是 a mod b 的逆元;
递归方法计算:
#include<stdio.h>
#define ll long long ll gcd(ll a,ll b,ll &d,ll& x,ll& y){
if(!b){
d=a;
x=;
y=;
return x;
}
else{
gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
return x;
} int main(){
ll a,b,d,x,y;
while(scanf("%lld%lld",&a,&b)!=EOF){
x=gcd(a,b,d,x,y);
printf("a:%lld->x:%lld\n",a,x);
// printf("a:%lld->x:%lld\nb:%lld->y:%lld\n",a,x,b,y);
}
return ;
}
循环方法计算:
#include<stdio.h> int main(){
int a,b;
while(scanf("%d%d",&a,&b)!=EOF){
int x=,y=,t; {
if(a!=&&b!=){
int b0=b,q;
while(a>){
q=a/b0;
t=b0;b0=a%b0;a=t;
t=y;y=x-q*y;x=t;
}
if(x<)x+=b;
}
} printf("a:%d->x:%d\n",a,x);
}
return ;
}
ll gcd(ll a,ll b){
if(a!=&&b!=){
int b0=b,q,t,x=,y=;
while(a>){
q=a/b0;
t=b0;b0=a%b0;a=t;
t=y;y=x-q*y;x=t;
}
if(x<)x+=b;
}
return x;
}
gcd模板(欧几里得与扩展欧几里得、拓展欧几里得求逆元)的更多相关文章
- HDU-3579-Hello Kiki (利用拓展欧几里得求同余方程组)
设 ans 为满足前 n - 1个同余方程的解,lcm是前n - 1个同余方程模的最小公倍数,求前n个同余方程组的解的过程如下: ①设lcm * x + ans为前n个同余方程组的解,lcm * x ...
- poj 1061 青蛙的约会 拓展欧几里得模板
// poj 1061 青蛙的约会 拓展欧几里得模板 // 注意进行exgcd时,保证a,b是正数,最后的答案如果是负数,要加上一个膜 #include <cstdio> #include ...
- hdu_1576A/B(扩展欧几里得求逆元)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others) Me ...
- ACM数论-欧几里得与拓展欧几里得
ACM数论——欧几里得与拓展欧几里得 欧几里得算法: 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd ...
- [POJ2115]C Looooops 拓展欧几里得
原题入口 这个题要找到本身的模型就行了 a+c*x=b(mod 2k) -> c*x+2k*y=b-a 求这个方程对于x,y有没有整数解. 这个只要学过拓展欧几里得(好像有的叫扩展欧几里德QA ...
- poj 1061 青蛙的约会+拓展欧几里得+题解
青蛙的约会+拓展欧几里得+题解 纵有疾风起 题意 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出 ...
- NOIP2012拓展欧几里得
拉板题,,,不说话 我之前是不是说过数据结构很烦,,,我想收回,,,今天开始的数论还要恶心,一早上听得头都晕了 先来一发欧几里得拓展裸 #include <cstdio> void gcd ...
- POJ 2891 Strange Way to Express Integers(拓展欧几里得)
Description Elina is reading a book written by Rujia Liu, which introduces a strange way to express ...
- POJ1061 青蛙的约会-拓展欧几里得
Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事 ...
随机推荐
- HTML基础知识(w3school)
http://www.w3school.com.cn/tags/tag_meta.asp
- English trip -- VC(情景课)4 D
What do you see? I can see three men in the pictrue. one older man is a doctor, two younger men are ...
- Confluence 6 管理多目录
这个页面描述了如果在 Confluence 中定义了多个目录服务器将会发生什么样的情况.例如你可能会有一个内部目录服务器同时你还可能有连接一个 LDAP 外部服务器或者使用多种类型的其他用户目录.当你 ...
- Leha and another game about graph CodeForces - 840B (dfs)
链接 大意: 给定无向连通图, 每个点有权值$d_i$($-1\leq d_i \leq 1$), 求选择一个边的集合, 使得删除边集外的所有边后, $d_i$不为-1的点的度数模2等于权值 首先要注 ...
- Python练习题--持续更新
1.你是一个高级测试工程师,现在要做性能测试,需要你写一个函数,批量生成一些注册使用的账号. 产生的账号是以@163.com结尾,长度由用户输入,产生多少条也由用户输入,用户名不能重复,用户名必须由大 ...
- python-day6---while循环
# while 条件:# 循环体的代码1# 循环体的代码2# 循环体的代码3# count=0# while count < 10:# print(count)# count+=1 # whil ...
- Oracle11g温习-第八章:归档日志
2013年4月27日 星期六 10:36 1.归档和非归档的区别 1) 归档会在日志切换时,备份历史日志,用于OLTP(在线事务处理系统),可以进行冷备份和热备份,可以实现数据库完全恢复.不完全恢复 ...
- notepad++插件安装
notepad安装目录的 plugins 下重启 notepad.exe程序即可 插件下载地址 : https://sourceforge.net/projects/npp-plugins/fil ...
- Vscode设置个人爱好
Vscode设置个人爱好 插件列表 abusaidm.html-snippets-0.1.0 adamwalzer.string-converter-0.0.9 AESSoft.aessoft-c ...
- 063——VUE中vue-router之重定向redirct的使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...