同余方程

拓展欧几里得 + 线性同余方程

匿名 (未验证) 提交于 2019-12-02 23:49:02
1. 辗转相除法(欧几里得算法)的证明: 1 int gcd(int a,int b){ 2 return b?gcd(b,a%b):a; 3 } 4 // 不用考虑a,b大小,会自己交换的 Ex_gcd用途:求关于 ax + by =gcd(a,b) 的所有整数解      思路:令g=gcd(a,b) ,若我们已知该方程一个特解x0,y0,则我们可以用某种方式求出所有整数解。 3. ①怎么求出这个特解?    已知 gcd(a,b) = gcd(b, a%b) 接下来讨论下两式有无关系   b * x2 + (a%b) * y2 = g(b,a%b) 可知: a * x1 + b * y1 = b * x2 + (a%b) * y2= b * x2 + (a - (a / b) * b) * y2= a * y2 + b * (x2 - (a / b) * y2) 则知道x2, y2 就可以知道x1, y1了。 因为最终辗转相除法递归出口是b=0,a为GCD,所以对 a*x+b*y=gcd(a,b) 来说,x=1,y=0;得到这个特解,在回溯回去,就可以得出原方程的一个特解   ②如何由该特解推出其他整数解?   1 void e_gcd(int a,int b,int &gcd,int &x,int &y) 2 { 3 if(b==0) 4 { 5 x=1; 6 y=0; 7

【线性同余方程】青蛙的约会

匿名 (未验证) 提交于 2019-12-02 23:05:13
模运算:   取模:计算除以m的余数,叫做对m取模   同余:将a,b对m取模的结果相同,记为 ( m o d m ) ( m o d m ( m o d m ),则有 ( m o d m ( m o d m ) 线性同余方程:   a,b是整数,形如 ax ≡ b (mod n),且x是未知整数的同余式称为 一元线性同余方程。   定理:同余方程 ax ≡ b (mod n) 对于未知数 x 有解,当且仅当 b 是 gcd(a,n)的倍数。否则方程无解。且方程有解时,方程有 gcd(a,n)个解。   这里根据取余的概念可以得出,假如 a%n = b 的话,可以写出一个等式 a = n*t +b;    求解线性同余方程的方法:这里根据上面很容易得出下面两个等式:     ax = n*y 1     b = n*y 2 + 余数   上面两式相减得 ax - b = n(y 1 -y 2   那么根据这个等式采用 扩展欧几里得算法 就能够得出 x 的值。也就解出了线性同余方程。 例题:青蛙的约会       思路: 因为线总长L,青蛙需要循环跳才有可能碰面。而循环跳的话那么它们的位置只能通过对L取余得到。根据题意,假设它们需要跳k次才能碰面,那么很容易得出这个同余组 ( m o d L )。 而 根据上面的讲解 我们也可以得到下面两个等式: 1     y + k*n = L

NOIp提高组 2012 同余方程

只谈情不闲聊 提交于 2019-11-29 14:17:56
同余:数论中的重要概念。给定一个正整数m,如果两个整数a和b满足(a-b)能够整除m,即(a-b)/m得到一个整数, 那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的一个等价关系。 数学上同余,两个整数除以同一个整数,若得相同余数,则二整数同余。 两个整数a、b,若它们除以整数m所得的余数相等,则称a与b对于模m同余或a同余于b模m 记作 a≡b (mod m) 读作 a同余于b模m,或读作a与b对模m同余。 例如 26≡2 (mod 12) 【定义】设m是大于1的正整数,a、b是整数,如果m|(a-b),则称a与b关于模m同余,记作a≡b(mod m),读作a与b对模m同余. 显然,有如下事实 (1)若a≡0(mod m),则m|a; (2)a≡b(mod m)等价于a与b分别用m去除,余数相同。 【证明】 充分性: m|(a-b)——> a≡b(mod m) 设a=mq1+r1,b=mq2+r2 且0≤r1,r2<m ∵ m|(a-b) 又a-b=m(q1-q2)+(r1-r2). ∴必有常数n使得(r1-r2)=mn 则有m|(r1-r2). ∵0≤r1,r2<m, ∴0≤|r1-r2|<m ∴r1-r2=0 即r1=r2. 故a≡b(mod m). 必要性:a≡b(mod m)——>m|(a-b) 设a,b用m去除余数为r, 即a=mq1+r,b

[模板]求解线性同余方程

这一生的挚爱 提交于 2019-11-29 00:18:11
求解a*x = b (mod p) #include<bits/stdc++.h> using namespace std; int exgcd(int a,int b,int& x,int& y) { int d=a; if(b){ d=exgcd(b,a%b,y,x); y-=(a/b)*x; } else{ x=1;y=0; } return d; } int gcd(int a,int b) { return !b?a:gcd(b,a%b); } int main() { int a,b,p; scanf("%d%d%d",&a,&b,&p);//计算 a*x = b (mod p) int x,y; int d=exgcd(a,p,x,y); if(b%d!=0) printf("-1\n"); else { x=(x)*b/d; x+=p; x%=p; for(int i=1;i<10;i++) { cout<<(x+(i-1)*p/d)<<endl; } } } 来源: https://www.cnblogs.com/cautx/p/11434444.html

同余问题(超详细!!!)

孤街醉人 提交于 2019-11-28 08:47:28
同余基本概念 剩余系 欧拉函数 欧拉函数 φ(n) 表示1~n中所有与n互质的数。比如1~8中与8互质的数有1,3,5,7,所以φ(8)=4。 公式1 :如果p是素数,有φ(p)=p-1。 公式2(积性) :如果(a,b)=1,有φ(a*b)=φ(a)*φ(b), --->以下是公式二的证明过程 设模a的一个简系为a1,a2,a3,…,aφ(a),模b的一个简系为b1,b2,b3,…,bφ(b) 现在我们要证明:所有ai∗b+bj∗a(共φ(a)*φ(b)个)组成了模a*b的一个简系(即φ(a*b)=φ(a)*φ(b))。 判定简系需要证明下面三点: (ai∗b+bj∗a,a∗b)=1。 ai∗b+bj∗a≢ak∗b+bt∗a(mod a∗b)(i!=k或j!=t) 对于任意k满足(k,a*b)=1,则一定有k≡ai∗b+bj∗a(mod a∗b)(即没有遗漏) 证明1: (ai∗b+bj∗a,a∗b)=1。 因为(a,ai)=1,(a,b)=1,所以(a,ai*b)=1,由辗转相除法可得(a,ai*b+bj*a)=(a,ai*b)=1,同理得(b,ai*b+bj*a)=1。 所以1得证。 证明2: ai∗b+bj∗a≢ak∗b+bt∗a(mod a∗b)(i!=k或j!=t) 证明3: 对于任意k满足(k,a*b)=1,则一定有k≡ai∗b+bj∗a(mod a∗b) 所以φ

gcd 和 同余方程(Exgcd)

我是研究僧i 提交于 2019-11-27 17:01:33
求关于 x 的同余方程 ax≡1(mod b) 的最小正整数解。 对于 100%的数据, 2≤a,b≤2*10 9 。 NOIP 2012 提高组 第二天 第一题 (只看Exgcd的自行跳过这段文字) 先撇开扩展欧几里得什么的不管,首先证明辗转相除法。 gcd(greatest common divisor),是一种计算两个数最大公约数的算法,时间复杂度为O(1)。简单来说,我们定义gcd(a,b)为a、b的最大公约数,那么gcd(a,b)=gcd(b,a mod b)。一般使用递归计算,在最后一层,a≡0(mod b)的时候,这一层的b即为答案。 下面给出证明: 令a>b,则存在正整数k、r,使得a=kb+r,而r≡a(mod b),所以我们要证明的结论就是gcd(a,b)=gcd(b,r)。 若r=0,那么以上结论显然。 那么,若r≠0呢? 假设gcd(a,b)=d,那么存在正整数p、q,使得a=pd,b=qd(p>q)。 所以pd=kqd+r,整理得r=(p-kq)d。因为r>0,所以pd>kqd,显然p-kq为正整数,所以r必为d的倍数,不难证明gcd(a,b)=gcd(b,r),也就是gcd(a,b)=gcd(b,a mod b)。 1 #include<bits/stdc++.h> 2 #define LL long long 3 using namespace std

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

风流意气都作罢 提交于 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

通过扩欧得出线性同余方程的通解以及x的最小正整数解

ぃ、小莉子 提交于 2019-11-26 15:55:19
同余定理 若 ax与b模m的余数相同(其中x为未知数,即所需要求的数),即 ax%m=b%m ,则这个式子可以记作成 a≡b (mod m) 。 设ax对m取模后的余数为r1,则有: ax=y1 m+r1。 ① 同理,设b对m取模后的余数为r2,则有: b=y2 m+r2。 ② 其中y1与y2均为任意整数,此时两则互不相干。 那么我们知道,由于ax%m=b%m,则 r1=r2 ,联立①②得:ax-y1 m=b-y2 m,移项最后得出方程: ax+my=b 这个方程叫 线性同余方程 ,由于未知数x为一阶的,所以也称为 一次同余方程。 这个方程的形式也使它叫作 不定方程。 这个方程的一个性质是:若至少有一组解(x0,y0)能使得这个方程成立,则当且仅当gcd(a,m)|b, 即a与m的最大公约数能被b整除。 (裴蜀定理) 如果我们直接求解的话,当然是不行的了~那么接下来会由扩展欧几里得算法来求出这个方程的通解。 在接下来之前,我们有牢记一个东西,方程ax+my=b,它是关于(x,y)的一个二元一次方程,切记它的 右半边式子是已知的数b。 (一般题目推出来,a、b、m都是已知的。求x,y) 设g=gcd(a,m), 而扩展欧几里得算法只是求方程:ax+my=g的一组特解。 扩展欧几里得算法 对于方程: ax+my=g ,用ex_gcd(扩欧)求出一组解(x0,y0)满足这个方程。