【hiho一下-95】 扩展欧几里得算法
来源:互联网 发布:网络与新媒体概论笔记 编辑:程序博客网 时间:2024/06/05 03:43
例题是hiho的一道题:
题目
这道题主要用到了欧几里得扩展算法,并且求一下最小正整数解就好了,没什么特别的。不过,再次学习了一下欧几里得扩展算法,有了更深的理解。欧几里得扩展算法可以有两种形式:
1. ax + by = c = bx +(a%b)y 证明很容易,根据欧几里得算法,设t=(a,b),a=k1*t, b=k2*t, (a%b)=k3*t,那么c也能表示成t的倍数,只要修改x和y,就一定能相等。
2. a*t1(k-1) + b*t2(k-1) = t3(k-1)
a*t1(k) + b*t2(k) = t3(k)
a*t1(k+1) + b*t2(k+1) = t3(k+1)
t3(k+1) = t3(k-1)%t3(k)
只要一直迭代下去,直到t3(k+1)=0,那么t3(k)就是最小公约数。有人可能会迷惑,这个公约数是谁和谁的呢?那么如果我们设置t3(0)=a,t3(1)=b,那么就是(a,b),由此可以得到最初的两个式子:
a*1 + b*0 = a
a*0 + b*1 = b
只要推理一下,就能得到递推公式:
t3(k+1) = t3(k-1) % t3(k)
t1(k+1) = t1(k-1) - t1(k)*tmp
t2(k+1) = t2(k-1) - t2(k)*tmp
tmp = t3(k-1)/t3(k)
证明方法请自行百度一下:证明
下面是题目的代码:
//// hiho.cpp// hiho//// Created by lhq on 16/4/25.// Copyright © 2016年 lhq. All rights reserved.//#include <iostream>#include <stdio.h>#include <math.h>using namespace std;/* ax + by = gcd = bx + a%by = bx + (a - a/b * b)y = ay + (x - a/b*y)b v1 > v2 s1 + v1*t = s2+ v2*t - km (v1-v2)*t + mk = s2 - s1 v2 > v1 s2 + v2*t = s1 + v1*t -km (v2-v1)*t + km = s1 - s2 at + mk = gcd 求t,k t,k > 0 且为整数 ax + by = gcd a*(x + b/gcd * u) b*(y - a/gcd * u) 求最小的x */// ax + by = c a = b , b = a%b 直到b = 0 主动改变a,blong long gcd_ex(long long& x, long long& y, long long a, long long b){ if(b == 0){ x = 1; y = 0; return a; } long long tmp = gcd_ex(x, y, b, a%b); long long tmpy = y; y = x - (a/b)*y; x = tmpy; return tmp;}// at1 + bt2 = t3 t3 = t1%t2 直到t3=1 主动改变x,y 注意:初始值设置为,t3(k-1)=a, t3(k)=b,所以肯定能得到t3=(a,b)long long gcd_ex_2(long long& x, long long& y, long long a, long long b){ long long to_1,to_2,to_3; long long tm_1,tm_2,tm_3; long long tn_1,tn_2,tn_3; //不存在最大公约数 if(a == 0 || b == 0){ x = y = 0; return 0; } to_1 = 1; to_2 = 0; to_3 = a; tm_1 = 0; tm_2 = 1; tm_3 = b; for(tn_3 = to_3%tm_3; tn_3!=0; tn_3=to_3%tm_3){ long long tmp = to_3 / tm_3; tn_1 = to_1 - tmp * tm_1; tn_2 = to_2 - tmp * tm_2; to_1 = tm_1; to_2 = tm_2; to_3 = tm_3; tm_1 = tn_1; tm_2 = tn_2; tm_3 = tn_3; } x = (tm_1%(b/tm_3) + b/tm_3)%(b/tm_3); //最小正整数解 y = (tm_2%(b/tm_3) + a/tm_3)%(a/tm_3); //最小正整数解 return tm_3;}int main(){ long long s1,s2,v1,v2,m; long long x,y,a,b,c,gcd; while(cin>>s1>>s2>>v1>>v2>>m){ a = (v1 - v2); b = m; c = (s2 - s1); if(a<0){ a = -a; c = -c; } if(c<0){ c += m; } gcd = gcd_ex_2(x, y, a, b);// gcd = gcd_ex(x, y, a, b); if(c % gcd){ cout<<-1<<endl; }else{ b = b/gcd; x = (x*c/gcd)%b; if(x>0){ cout<<x<<endl; }else{ while(x<0){ x += b; } cout<<x<<endl; } } } return 0;}
- 【hiho一下-95】 扩展欧几里得算法
- hiho一下 KMP 算法
- 欧几里得算法&&扩展欧几里得算法
- 欧几里得算法/扩展欧几里得算法
- 欧几里得算法&&扩展欧几里得算法
- hiho 1297 数论四·扩展欧几里得
- 欧几里得、扩展的欧几里得算法
- 欧几里得及欧几里得扩展算法
- 欧几里得、扩展的欧几里得算法 .
- 欧几里得与扩展欧几里得算法
- 欧几里得和扩展欧几里得算法
- 欧几里得和扩展欧几里得算法
- 欧几里得算法及扩展欧几里得
- 欧几里得和扩展欧几里得算法
- 欧几里得, 扩展欧几里得算法模板
- hiho一下~week_3 KMP算法
- 欧几里得算法及其扩展
- 扩展的欧几里得算法
- hdu_5672_Strings BestCoder Round #81 (div2)
- 如何克服录制回放模式的弊端
- 【小技巧】制作一个滑动过渡切换的导航条
- Codeforces #669 Div2 C. Little Artem and Matrix(模拟)
- ERROR 1203 (42000): User root already has more than 'max_user_connections' active connections
- 【hiho一下-95】 扩展欧几里得算法
- WPF样式和行为
- CountDownLatch理解一:与join的区别 Done
- HTTP协议的状态码
- mysql 语句优化
- String.format()用法
- 阿里移动推荐-Markel
- Android 中AIDL的使用与理解
- Android studio git 回滚文件到上一个版本的