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)简要介绍的更多相关文章

  1. 2020牛客寒假算法基础集训营4 -- A : 欧几里得

    A:欧几里得 考察点 : 递推, gcd 坑点 : long long 这道题题解说的十分详细,是裴波那契的一种变形,只不过换成 gcd 了. Code: #include <cstdio> ...

  2. POJ - 1061 青蛙的约会 (扩展欧几里得求同余式)

    题意:两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对 ...

  3. [poj1061]青蛙的约会<扩展欧几里得>

    题目链接:http://poj.org/problem?id=1061 其实欧几里得我一直都知道,只是扩展欧几里得有点蒙,所以写了一道扩展欧几里得裸题. 欧几里得算法就是辗转相除法,求两个数的最大公约 ...

  4. 【洛谷】【扩欧】P1516 青蛙的约会

    [题目描述] 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有 ...

  5. gcd,扩展欧几里得,中国剩余定理

    1.gcd: int gcd(int a,int b){ ?a:gcd(b,a%b); } 2.中国剩余定理: 题目:学生A依次给n个整数a[],学生B相应给n个正整数m[]且两两互素,老师提出问题: ...

  6. hdu 5512 Pagodas 扩展欧几里得推导+GCD

    题目链接 题意:开始有a,b两点,之后可以按照a-b,a+b的方法生成[1,n]中没有的点,Yuwgna 为先手, Iaka后手.最后不能再生成点的一方输: (1 <= n <= 2000 ...

  7. GCD nyoj 1007 (欧拉函数+欧几里得)

    GCD  nyoj 1007 (欧拉函数+欧几里得) GCD 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 The greatest common divisor ...

  8. gcd模板(欧几里得与扩展欧几里得、拓展欧几里得求逆元)

    gcd(欧几里得算法辗转相除法): gcd ( a , b )= d : 即 d = gcd ( a , b ) = gcd ( b , a mod b ):以此式进行递归即可. 之前一直愚蠢地以为辗 ...

  9. 算法马拉松35 E 数论只会Gcd - 类欧几里得 - Stern-Brocot Tree - 莫比乌斯反演

    题目传送门 传送门 这个官方题解除了讲了个结论,感觉啥都没说,不知道是因为我太菜了,还是因为它真的啥都没说. 如果 $x \geqslant y$,显然 gcd(x, y) 只会被调用一次. 否则考虑 ...

随机推荐

  1. 洛谷P2505 [HAOI2012]道路(最短路计数)

    传送门 早上模拟赛考这题,结果竟然看错题目了orz 然后下午看完题解自己做的时候空间开小了白WA了好久orz 首先,如果以$S$为起点,一条边$(u,v)$在最短路上,则$dis[u]+edge[i] ...

  2. 修改jq weui自定义对话框点击确定按钮不关闭对话框

    如果我们在对话框给用户输入值时,当用户输入空值点击确定按钮时,应该给个提示然后让用户继续输入. 如果在方法里使用 return false;,结果用户输入空值时对话框还是会关闭.正确做法如下: 先设置 ...

  3. centos 7.3 安装vmtools,解决无法编译共享文件夹模块

    环境说明: vmware 12.5.0 build-4352439 centos 7.3.1611   64位,内核版本:Linux version 3.10.0-514.16.1.el7.x86_6 ...

  4. Python爬虫|爬取喜马拉雅音频

    "GOOD Python爬虫|爬取喜马拉雅音频 喜马拉雅是知名的专业的音频分享平台,用户规模突破4.8亿,汇集了有声小说,有声读物,儿童睡前故事,相声小品等数亿条音频,成为国内发展最快.规模 ...

  5. 解读ping -n 4 127.1 >nul 2>nul

    命令解读 ping是Windows.Unix和Linux系统下的一个命令.ping也属于一个通信协议,是TCP/IP协议的一部分.利用"ping"命令可以检查网络是否连通,可以很好 ...

  6. nginx 一些配置

    worker_processes 4; #工作进程数 events { #epoll是多路复用IO(I/O Multiplexing)中的一种方式, #仅用于linux2.6以上内核,可以大大提高ng ...

  7. Gym - 101810B ACM International Collegiate Programming Contest (2018)

    bryce1010模板 http://codeforces.com/gym/101810 #include <bits/stdc++.h> using namespace std; #de ...

  8. 106 Construct Binary Tree from Inorder and Postorder Traversal 从中序与后序遍历序列构造二叉树

    给定一棵树的中序遍历与后序遍历,依据此构造二叉树.注意:你可以假设树中没有重复的元素.例如,给出中序遍历 = [9,3,15,20,7]后序遍历 = [9,15,7,20,3]返回如下的二叉树:    ...

  9. python采用sqlachmy购物商城

    一.流程图: 二.目录结构: C:\USERS\DAISY\PYCHARMPROJECTS\S12\MARKET │ __init__.py │ __init__.pyc │ ├─backend │ ...

  10. TI德州芯片TLV系列和TPS系列芯片区别(转)

    TLV和TPS一般会有pin to pin的对应型号: 一般来讲,TPS精度.准确度和性能会好一些,所以价钱要贵一些: 对应TLV就是一样可以实现上述功能,但是精度和性能等级是稍微低一点的: 具体选择 ...