欧几里得

[数论]拓展欧几里得算法

冷暖自知 提交于 2019-11-28 15:20:59
欧几里得算法(辗转相除法) 用来求解最大公约数 1 int gcd(int a,int b){ 2 return b ? gcd(b,a%b) : a; 3 } 在 #include<algorithm> 中也可以直接调用 __gcd(a,b) 拓展欧几里得算法 求解不定方程: 引理:存在 x , y 使得 gcd(a,b)=ax+b 1 typedef long long ll; 2 3 ll exgcd(ll a,ll b) 4 { 5 if(b){ 6 ll r=exgcd(b,a%b); 7 ll k=x; 8 x=y; 9 y=k-a/b*y; 10 return r; 11 } 12 else{ 13 x=1,y=0; 14 return a; 15 } 16 } 解线性同余方程 关于 x 的模方程 ax%b=c 的解,方程转换为 ax+by=c 其中 y 一般为非正整数,则问题变为用 exgcd 解不定方程 计算乘法逆元 若 a*x≡1(mod b) ,且 a与 b互质,那么我们就能定义: x为 a的逆元 这就是利用拓欧求解线性同余方程 a*x≡c(mod b) 的 c=1 的情况。我们就可以转化为解 a*x + b*y = 1这个方程 1 typedef long long ll; 2 3 void exgcd(ll a,ll b)//扩展欧几里得算法求乘法逆元

类欧几里得算法

*爱你&永不变心* 提交于 2019-11-28 11:13:03
  对于求和式 $f(a,b,c,n)=\sum_{i=0}^n \lfloor \frac{ai+b}{c} \rfloor$   当 $a \geq c$ 或 $b \geq c$ 时,设 $a'=a \; mod \; c$,$b'=b \; mod \; c$,有 $$\begin{align*} f(a,b,c,n) = & \sum_{i=0}^n \; \lfloor \frac{ai+b}{c} \rfloor \\ = & \sum_{i=0}^n \; \lfloor \frac{a'i+b'}{c} \rfloor + \lfloor \frac{a}{c} \rfloor \times i + \lfloor \frac{b}{c} \rfloor \\ = & \; f(a',b',c,n) + \frac{n(n+1)}{2} \times \lfloor \frac{a}{c} \rfloor + (n+1) \times \lfloor \frac{b}{c} \rfloor \end{align*}$$   当 $a<c$ 且 $b<c$ 时,设 $m= \lfloor \frac{an+b}{c} \rfloor$,有 $$\begin{align*} f(a,b,c,n) = & \sum_{i=0}^n \; \lfloor \frac{ai

扩展欧几里得算法的思想与推导

佐手、 提交于 2019-11-28 06:27:18
偶然看到 大神 Katoumegumi 的欧几里得推导过程,感觉非常接地气。借此收藏。 对于一个方程 a ∗ x + b ∗ y = g c d ( a , b ) 来说,我们可以做如下的推导: 设有 a ∗ x 1 + b ∗ y 1 = g c d ( a , b ) ; 同时我们有 b ∗ x 2 + ( a % b ) ∗ y 2 = g c d ( b , a % b ) ; 对于这个方程组,我们希望知道的是 x 1 , x 2 , y 1 , y 2 之间的关系,这样我们才可以递归解决这个问题 我们观察 b ∗ x 2 + ( a % b ) ∗ y 2 这个式子,我们可以将 ( a % b ) 写作 ( a − ⌊ a b ⌋ ∗ b ) ,将括号打开常数 a , b 合并,合并之后的结果为 a ∗ y 2 + b ∗ ( x 2 − ⌊ a b ⌋ ∗ y 2 ) ) 由于欧几里得算法的原理 g c d ( a , b ) == g c d ( b , a % b ) ,我们将两式子联立,对比系数即可得到 x 1 = y 2 , y 1 = x 2 − ⌊ a b ⌋ ∗ y 2 这个递归的边界是什么呢?我们知道,当朴素欧几里得到达边界时, r e t u r n g c d ( a , 0 ) = a ,那么边界条件就是对 a ∗ x 0 + b ∗ y 0 =

浅谈欧几里得算法(辗转相除法)证明

大兔子大兔子 提交于 2019-11-28 05:08:40
前言 之前只知道一味的背辗转相除法的biao,连它是欧几里得算法都不知道,所以决定写一篇证明 百度百科了解一下 欧几里德算法又称 辗转相除法 ,是指用于计算两个 正整数 a,b的 最大公约数 。应用领域有数学和计算机两个方面。 计算公式gcd(a,b) = gcd(b,a mod b)。 //这就是我接下来要证明的东东 证明 假设 1.求n、m的最小公倍数 2、a、b分别是 m div n 和 m mod n,即 m = na + b 3、gcd(m,n)表示m、n的最大公因数 求证:gcd(m,n) = gcd(n,b),也就是gcd(x,y)=gcd(y,x mod y)//上面说的那个 证:设c=gcd(m,n),d=gcd(n,b) (1): 因为 c 为m,n的公因数 所以 c | m,c | n //“|” 是整除符号,x | y代表x是y的因数 所以 c | na //n乘任意整数都是c的倍数 所以 c | (m - na) 即 c | b //因为m和na都是c的倍数,所以相减也是 所以 c 为 n,b 的公因数 因为 d 是 n,b 的最大公因数 所以 c <= d (2):同理可证 d <= c 因为 d 为n,b的公因数 所以 d | n , d | b //“|” 是整除符号,x | y代表x是y的因数 所以 d | na //n乘任意整数都是d的倍数 所以

数论集合

耗尽温柔 提交于 2019-11-27 16:20:25
零,前言: 学chty_sqy开个数论集合 学OI的时候以看数论就头大,现在该还了 T_T 建议推导和证明不熟或不会的同学动手推导 而且公式看上去不太清楚,学习的同学请仔细阅读 以前数论怎么都学不会,主要还是浮躁,不仔细看,没有动手 orz 一,gcd(欧几里得算法): 两个数a和b的最大公因数被称为gcd(a, b) 求gcd通常用欧几里得算法 原理:gcd(a, b)=gcd(b, a%b) 详情: https://www.cnblogs.com/cdcq/p/11366100.html 代码: 1 int gcd(int a,int b){ return b ? gcd(b,a%b) : a;} 一行gcd 二,exgcd(扩展欧几里得算法): 数论守门员 有一个或者几个变量的整系数方程,它们的求解仅仅在整数范围内进行。 扩展欧几里得算法研究的是形如 a*x+b*y=c 的丢番图方程的解 方程有解当且仅当gcd(a, b)|c 原理:a*x1+b*y1=gcd(a, b),b*x2+(a%b)*y2=gcd(b, a%b),gcd(a, b)=gcd(b, a%b) => x1=y2,y1=(x2-⌊a/b⌋*y2) 详情: https://www.cnblogs.com/cdcq/p/11366100.html 代码: 1 void exgcd(int a,int b

数论集合

你说的曾经没有我的故事 提交于 2019-11-27 13:57:25
零,前言: 学chty_sqy开个数论集合 学OI的时候以看数论就头大,现在该还了 T_T 建议推导和证明不熟或不会的同学动手推导 而且公式看上去不太清楚,学习的同学请仔细阅读 以前数论怎么都学不会,主要还是浮躁,不仔细看,没有动手 orz 一,gcd(欧几里得算法): 1.定义:gcd的意思是最大公约数,通常用扩展欧几里得算法求 原理:gcd(a, b)=gcd(b, a%b) 2.证明: 令d=gcd(a, b) => a=m*d,b=n*d 则m*d=t*n*d+a%b => a%b=d*(m-t*n) gcd(b, a%b)=gcd(n*d, (m-t*n)*d) 令gcd(n, m-t*n)=e => n=x*e,m-t*n=y*e 则m-x*e*n=y*e => m=e*(x*n+y) 由gcd(n, m)=1知gcd(e*(x*n+y), e*x)=1 故e=1 故gcd(n*d, (m-t*n)*d)=d即gcd(b, a%b)=gcd(a, b) 3.边界: 当b=0时return a 可以视为gcd(a, 0)=a,任何数都能整除0 也可以视为gcd(a, b)=b,这里的a和b是上一层的,满足a%b=0 4.特殊情况: 当a<b时,a%b=a,所以在下一层gcd(b, a%b)中相当于把a与b交换 5.代码: 1 int gcd(int a,int b){

扩展欧几里得求线性同余方程

风流意气都作罢 提交于 2019-11-27 13:39:52
https://www.acwing.com/problem/content/880/ #include <bits/stdc++.h> using namespace std; int ex_gcd(int a,int b,int &x,int &y) { if (!b) { x=1,y=0; return a; } int d=ex_gcd(b,a%b,y,x); y-=a/b*x; return d; } int main() { int t; scanf("%d",&t); while(t--) { int a,b,m; int x,y; cin>>a>>b>>m; int d=ex_gcd(a,m,x,y); if(b%d) puts("impossible"); else printf("%lld\n",(long long)b/d*x%m); } return 0; } 来源: https://blog.csdn.net/qq_43716912/article/details/99684587

8.14 数论 - 扩展欧几里得定理 与 同余方程

烂漫一生 提交于 2019-11-27 09:33:57
扩展欧几里得定理用于解方程 ax + by = gcd(a,b) int Exgcd(int a, int b, int &x, int &y) { if (!b) { x = 1; y = 0; return a; } int d = Exgcd(b, a % b, x, y); int t = x; x = y; y = t - (a / b) * y; return d; } 证明见: https://oi-wiki.org/math/gcd/ 通过欧几里得定理构造等价的方程,进行递归求解; 线性同余方程: 形如 ax ≡ c(mod b)的方程; 1. 等价: 等价于 ax + by = c ,两边同时取余就一样了 2. 判定条件:exgcd 可求 ax + by = gcd(a,b)的解 ,所以c是gcd(a,b)的整数倍时,时方程ax + by = c 有解 3. 通解: 求解后可根据原方程构造通解: x + k*b/gcd ,y - k*a/gcd 4.最小正整数解: 根据通解的形式 ,可得x的最小正整数解为 (x%t + t)%t ,t = b/gcd; int ex_gcd(int a, int b, int& x, int& y) { if (b == 0) { x = 1; y = 0; return a; } int d = ex_gcd(b, a % b,

拓展欧几里得算法求不定方程

心已入冬 提交于 2019-11-27 07:44:45
对于          ax+by=gcd(a,b) 这样的方程,可以用扩展欧几里得算法exgcd求出一组通解。 根据欧几里得求gcd:          gcd(a,b)=gcd(b,a%b) 可得          bx+(a%b)y=gcd(b,a%b) 根据       a%b=a−(a/b)∗b 可得          bx+ay−(a/b)b∗y=gcd(b,a%b) 化简得          ay+b(x−(a/b)y)=gcd(b,a%b)         x ′ = y , y ′ = ( x − ( a / b ) y )     a x ′ + b y ′ = g c d ( b , a % b ) < = > a x + b y = g c d ( a , b ) 根据       gcd(a,0)=a 一直递归直到b为0时可得       ax+by=a 可以得出一组平凡解            x=1,y=0 所以一直递归下去可以得出一组平凡解,然后再往回带得出ax+by=gcd(a,b)的一组解( x ′ = y , y ′ = ( x − ( a / b ) y ) ) 泛化来看不定方程 ax+by=c 只有满足 c%gcd(a,b)==0 才有解。 求解同余方程可以用费马小定理来求也可以用拓展欧几里得来求 ax≡b mod n <==>ax+ny