欧几里得(辗转相除gcd)、扩欧(exgcd)、中国剩余定理(crt)、扩展中国剩余定理(excrt)简要介绍
1.欧几里得算法(辗转相除法)
直接上gcd和lcm代码。
int gcd(int x,int y){
return y==?x:gcd(y,x%y);
}
int lcm(int x,int y){
return x*y/gcd(x,y);
}
2.扩欧:exgcd:对于a,b,一定存在整数对(x,y)使ax+by=gcd(a,b)=d ,且a,b互质时,d=1。 x,y可递归地求得。
我懒得改返回值类型了
long long exgcd(long long a,long long b,long long &x,long long &y){
long long d=a;
if(b==) y=,x=;
else{
d = exgcd(b,a%b,y,x);
y -= a/b*x;
}
return d;
}
求解 x,y的方法的理解:
设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1 = bx2+ (a mod b)y2;
即:ax1+ by1 = bx2+ (a - [a / b] * b)y2
= ay2+ bx2- [a / b] * by2;
= ay2+ b(x2- [a / b] *y2);
所以:x1=y2; y1=x2- [a / b] *y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
这个思想是递归的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
3.中国剩余定理(Chinese remainder theorem)
截自百度百科:

要求模下的唯一解,关键是求逆元。
拓展欧几里得如何求逆元:
当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 的逆元;
求逆元也可单写为函数:a在模b意义下的逆元:inv(a,b);
long long inv(long long a, long long b){
exgcd(a,b,x,y);
while(x<) x+=b;
return x;
}
51nod中还有个求乘法逆元的题,直接应用扩欧求逆元即可。
最后上crt完整代码:
long long crt(){//pri数组和re数组分别保存质数和余数 也就是上图方程组中的mi和ai
long long m=,ans=;
for(int i=;i<n;i++){
m*=pri[i];
}
for(int i=;i<n;i++){
long long mi=m/pri[i],x,y;
exgcd(mi,pri[i],x,y); //exgcd的应用:求得逆元x
ans=(ans+re[i]*x*mi)%m;//加和求模下的唯一解
}
while(ans<) ans+=m;
return ans;
}
例题:51nod 1079中国剩余定理 http://www.51nod.com/Challenge/Problem.html#!#problemId=1079
#include <iostream>
using namespace std;
int n;
long long pri[],re[];//分别保存质数,和取余的结果
//利用扩展欧几里得求乘法取模运算的逆元
long long exgcd(long long a,long long b,long long &x,long long &y){
long long d=a;
if(b==) y=,x=;
else{
d=exgcd(b,a%b,y,x);
y-=a/b*x;
}
return d;
}
//Chinese remainder theorem
long long crt(){
long long m=,ans=;
for(int i=;i<n;i++){
m*=pri[i];
}
for(int i=;i<n;i++){
long long mi=m/pri[i],x,y;
exgcd(mi,pri[i],x,y);
ans=(ans+re[i]*x*mi)%m;
}
if(ans<) ans+=m;
return ans;
}
int main(){
cin>>n;
for(int i=;i<n;i++){
cin>>pri[i]>>re[i];
}
cout<<crt()<<endl;
return ;
}
4.扩展中国剩余定理(excrt)
如果人家给的除数不是质数怎么办?就要先处理线性同余方程组了。
我太笨了当时看了好久还是不会,现在稍微明白点了但还是迷迷糊糊,具体分析过程可以看这个dalao的blog,过程很详细:https://www.cnblogs.com/zwfymqz/p/8425731.html
放一个参考人家修修改改写的题目吧。POJ2891
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std; const ll MAXN = 1e6 + ;
ll K, C[MAXN], M[MAXN], x, y; ll gcd(ll a, ll b) {
return b == ? a : gcd(b, a % b);
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
ll r=a;
if (b == ) x = , y = ;
else{
r = exgcd(b, a % b, y, x);
y -= (a / b) * x;
}
return r;
}
ll inv(ll a , ll b){//求逆元
exgcd(a,b,x,y);
while(x<) x+=b;
return x;
} int main(){
while(cin>>K){
for (ll i = ; i <= K; i++) scanf("%lld%lld", &M[i], &C[i]);
bool flag = ;
for (ll i = ; i <= K; i++) {
ll M1 = M[i - ], M2 = M[i];
ll C2 = C[i], C1 = C[i - ];
ll T = gcd(M1, M2); if ((C2 - C1) % T != ) { flag=; break; }
M[i] = (M1 * M2) / T;
C[i] = ( inv( M1 / T , M2 / T ) * (C2 - C1) / T ) % (M2 / T) * M1 + C1;
C[i] = (C[i] % M[i] + M[i]) % M[i];
}
if(flag) cout<<C[K]<<endl;
else cout<<-<<endl; }
return ;
}
欧几里得(辗转相除gcd)、扩欧(exgcd)、中国剩余定理(crt)、扩展中国剩余定理(excrt)简要介绍的更多相关文章
- 2020牛客寒假算法基础集训营4 -- A : 欧几里得
A:欧几里得 考察点 : 递推, gcd 坑点 : long long 这道题题解说的十分详细,是裴波那契的一种变形,只不过换成 gcd 了. Code: #include <cstdio> ...
- POJ - 1061 青蛙的约会 (扩展欧几里得求同余式)
题意:两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对 ...
- [poj1061]青蛙的约会<扩展欧几里得>
题目链接:http://poj.org/problem?id=1061 其实欧几里得我一直都知道,只是扩展欧几里得有点蒙,所以写了一道扩展欧几里得裸题. 欧几里得算法就是辗转相除法,求两个数的最大公约 ...
- 【洛谷】【扩欧】P1516 青蛙的约会
[题目描述] 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有 ...
- gcd,扩展欧几里得,中国剩余定理
1.gcd: int gcd(int a,int b){ ?a:gcd(b,a%b); } 2.中国剩余定理: 题目:学生A依次给n个整数a[],学生B相应给n个正整数m[]且两两互素,老师提出问题: ...
- hdu 5512 Pagodas 扩展欧几里得推导+GCD
题目链接 题意:开始有a,b两点,之后可以按照a-b,a+b的方法生成[1,n]中没有的点,Yuwgna 为先手, Iaka后手.最后不能再生成点的一方输: (1 <= n <= 2000 ...
- GCD nyoj 1007 (欧拉函数+欧几里得)
GCD nyoj 1007 (欧拉函数+欧几里得) GCD 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 The greatest common divisor ...
- gcd模板(欧几里得与扩展欧几里得、拓展欧几里得求逆元)
gcd(欧几里得算法辗转相除法): gcd ( a , b )= d : 即 d = gcd ( a , b ) = gcd ( b , a mod b ):以此式进行递归即可. 之前一直愚蠢地以为辗 ...
- 算法马拉松35 E 数论只会Gcd - 类欧几里得 - Stern-Brocot Tree - 莫比乌斯反演
题目传送门 传送门 这个官方题解除了讲了个结论,感觉啥都没说,不知道是因为我太菜了,还是因为它真的啥都没说. 如果 $x \geqslant y$,显然 gcd(x, y) 只会被调用一次. 否则考虑 ...
随机推荐
- [Noip2012普及组]摆花
Description 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m 盆.通过调查顾客的喜好,小明列出了顾客最喜欢的 n 种花,从 1 到 n 标号.为了在门口展出更多种花,规定 ...
- B - Halloween Costumes
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...
- JVM加载类的原理机制
在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载.链接和初始化,其中链接又可以分成校验.准备.解析装载:查找和导入类或接口的二进制数据: 链接:执行下面的校验.准备和解析 ...
- DRF教程5-API接口文档和接口测试
配置 配置好,就可以访问web页面 pip install coreapi #安装依赖 from rest_framework.documentation import include_docs_ur ...
- Codeforces Round #533(Div. 2) B.Zuhair and Strings
链接:https://codeforces.com/contest/1105/problem/B 题意: 给一个字符串和k,连续k个相同的字符,可使等级x加1, 例:8 2 aaacaabb 则有aa ...
- compare `lvs/haproxy/nginx`
特性 LVS Nginx Haproxy 工作层 四层(传输层TCP/UDP) 七层(应用层) 四层.七层 应用范围 基于TCP和UDP之上的协议都可以 Http.mail HTTP.TCP之上应用 ...
- H5 之 Page Visibility
这个是今天刚发现的,想起之前那个在页面用video标签视频播放,别人切换页面后仍在继续播放,体验很不好,用这个API就可以很完美的解决. Page Visibility API 可以让你获取到这种状态 ...
- Unity Shader入门精要学习笔记 - 第5章 开始 Unity Shader 学习之旅
一个顶点/片元 着色器的结构大概如下: Shader "MyShaderName" { Properties { //属性 } SubShader { //针对显卡A的SubSha ...
- 一个简易的Http请求转发器
这两天一直再看微信开发,临时在我的电脑搭了个IIS服务器做微信开发,外网也能访问了,关键是,调试太麻烦了!! 我写完代码,要将代码发布到IIS才能接收微信消息,可是在这个过程中,我不知道微信发过来的是 ...
- ES-Mac OS环境搭建(2)
下载 进入官网,选择downloads进入下载页. 选择elasticsaerch下载. 新的页面中,下拉选择历史版本. 下拉选择elasticsearch和版本,然后点击下载. 选择MACOS/LI ...