基础数论算法(2) GCD LCM EXGCD 学习笔记
来源:互联网 发布:淘宝刷单好评 编辑:程序博客网 时间:2024/05/02 02:16
继续学习数论……
本文除非特殊说明,所有的数都是整数
本文参考:欧几里德与扩展欧几里德算法
一、gcd
long long gcd(long long x,long long y){ return y==0?x:gcd(y,x%y);}
应该没什么好说的吧……非常朴素的算法
还有一种位运算优化,感觉实现起来非常复杂,NOIP也不大可能卡这个所以就不谈了……
二、lcm
只需要记住一个公式:lcm(x,y)=x*y/gcd(x,y)
随便求→_→
三、EXgcd
那么终于要来到数论2面的道中BossEXgcd 明明是EXgcd为什么不是EX面啊
EXgcd用于解决这样一类问题:
已知(a,b),求解一组(p,q),使得pa+qb=gcd(a,b).
解是一定存在的,根据是数论中的某个相关定理。
那么怎么求呢?
pa+qb=gcd(a,b)=gcd(b,a%b)=pb+q(a%b)=pb+q(a-
显然p、q都是单调递减的。而我们在无数次的gcd过程中,b的值最终变成0,即p*a=a,显然此时p=1,q=0是一组解。那么我们有没有办法逆推回去?答案是肯定的。实现:
#include <iostream>using namespace std;typedef long long LL;LL exgcd(LL a,LL b,LL &x,LL &y){ if(!b){ x=1,y=0; return a; } LL gcd,tmp; gcd=exgcd(b,a%b,x,y); tmp=x; x=y,y=tmp-a/b*y; return gcd;}int main(){ LL a,b,x,y,z; cin>>a>>b; z=exgcd(a,b,x,y); cout<<z<<" "<<x<<" "<<y<<endl; return 0;}
四、EXgcd的应用
(一)EXgcd求解不定方程与线性同余方程
定理2.1 对于方程ax+by=c,该方程有整数解的充要条件是c%gcd(a,b)=0
我们可以用扩欧找出
我们不妨先找出
定理2.2 方程ax+by=gcd(a,b)的解为
由此可以方便的求出。
从此得到原方程的解:
定理2.3 方程ax+by=c若有整数解,则其整数解为方程ax+by=gcd(a,b)的解乘
如果要求最小正整数解的话:
定理2.4 当t=
而对于线性同模方程
定理2.5 方程ax
好了,定理都说完了,玄学竞赛是不需要证明的,所以我们直接来看一下代码。
#include <iostream>#include <vector>using namespace std;typedef long long LL;LL exgcd(LL a,LL b,LL &x,LL &y){ if(!b){ x=1,y=0; return a; } LL gcd,tmp; gcd=exgcd(b,a%b,x,y); tmp=x; x=y,y=tmp-a/b*y; return gcd;}vector<pair<LL,LL> > v;bool work(LL a,LL b,LL c,LL l,LL r,LL L,LL R){ LL x,y; LL gcd=exgcd(a,b,x,y); if(c%gcd) return false; x*=c/gcd,y*=c/gcd; v.push_back(make_pair(x,y)); for(LL p=x+b,q=y-a;p<=r&&p>=l&&q<=R&&q>=L;p+=b,q-=a) v.push_back(make_pair(p,q)); for(LL p=x-b,q=y+a;p<=r&&p>=l&&q<=R&&q>=L;p-=b,q+=a) v.push_back(make_pair(p,q)); return true;}int main(){ LL a,b,c,l,r,L,R; cin>>a>>b>>c>>l>>r>>L>>R; if(work(a,b,c,l,r,L,R)){ vector<pair<LL,LL> >::iterator it; for(it=v.begin();it!=v.end();++it) cout<<it->first<<" "<<it->second<<endl; }}
(二)exgcd求逆元
逆元是很重要的,逆元是很重要的,逆元是很重要的。
所以掌握逆元的求法是很有必要的事情。
至于逆元怎么用我们之后再提.
逆元的定义:ax
由定义可知,其实我们是在求ax+by=1的解,典型的exgcd应用
那么实现方法:
void exgcd(int a,int b,int c,int &x,int &y){ if(a==0){ x=0,y=c/b; return; }else{ int tx,ty; exgcd(b%a,a,tx,ty); x=ty-(b/a)*tx; y=tx; return; }}
那么相关的例题我们之后和逆元一起说吧,因为逆元大概凑不够字数orz
- 基础数论算法(2) GCD LCM EXGCD 学习笔记
- [UVa 11889] Benefit (基础数论+GCD+LCM)
- 数论专题小结:gcd算法与exgcd算法
- 扩展欧几里得算法(exgcd) 学习笔记
- 【模板】【数论】gcd和exgcd
- uva 11388 - GCD LCM(数论)
- UVa 11388 - GCD LCM (简单数论)
- Hdu 4497 GCD and LCM(数论)
- HDU4497:GCD and LCM(数论)
- GCD & LCM (数学基础)
- <模板>(Miller-Rabin和Pollard_rho算法)poj 2429 GCD & LCM Inverse (数论)
- UVA 11388 GCD LCM (数论)
- UVA 11388 - GCD LCM(数论)
- ZOJ 1577 GCD & LCM 数论
- 欧几里得算法(GCD)和扩展欧几里得算法(EXGCD)
- 数论(一)——素数,GCD,LCM
- hdu 4497 GCD and LCM(数论,排列组合)
- 理论: 数论(1):整除、gcd以及lcm
- 从零开始的uboot系统移植5
- JVM学习笔记(8)-锁优化技术
- VECTOR中pair的排序
- PAT题解——1075. PAT Judge (25)
- PAT 乙级 1023.组个最小数(20)
- 基础数论算法(2) GCD LCM EXGCD 学习笔记
- Class类文件结构
- Office2013 完美激活
- Day3:msfconsole控制台终端
- Element UI 自定义正则表达式验证
- hexo的Next创建categories
- 金融企业软件测试中心筹备书-全生命周期管理篇
- java常见的异常处理汇总
- epoll