线性同余方程

AcWing 878 线性同余方程

我们两清 提交于 2020-01-14 00:24:41
题目描述: 给定n组数据ai,bi,mi,对于每组数求出一个xi,使其满足ai∗xi≡bi(mod mi),如果无解则输出impossible。 输入格式 第一行包含整数n。接下来n行,每行包含一组数据ai,bi,mi。 输出格式 输出共n行,每组数据输出一个整数表示一个满足条件的xi,如果无解则输出impossible。 每组数据结果占一行,结果可能不唯一,输出任意一个满足条件的结果均可。 输出答案必须在int范围之内。 数据范围 1≤n≤10^5,1≤ai,bi,mi≤2∗10^9 输入样例: 2 2 3 6 4 3 5 输出样例: impossible 7 分析: a∗x≡b(mod m)等价于ax - my' = b,令y = -y',得到ax + my = b,便可以使用扩展欧几里得算法进行求解了。当gcd(a,m) | b时,该线性同余方程有解,否则无解。我们只需先求解ax + my = gcd(a,m)的解,然后对系数x和y扩大b / gcd(a,m)倍即可得到方程ax + my = b的解了。 更一般的,ax+by =c的特解为x0,y0,d=gcd(a,b),则方程的通解为x = x0 + kb/d,y = y0 - ka/d。k为任意整数,这是因为想要在x中加上的参数乘上a后与另一项参数乘以b后抵消,即a(x+z1)+b(y-z2)=c,可以得到az1=bz2

C Looooops POJ - 2115

陌路散爱 提交于 2019-12-06 15:18:48
数论好题。。 香! 首先我们看到这一题, 题意是 \[ a + c * x \equiv b (mod \ \ 2 ^ k)\] 对此式移一下项, 得 \[ c * x \equiv b - a (mod \ \ 2 ^ k)\] 此时原式为标准线性同余方程。 \(exgcd\) 解得 \(x\) 后,x 要做如下处理 : 设 \(g = gcd(b - a, 2 ^ k), k = 2 ^ k, d = b - a\) 1#. \(x = x * (d / g)\) , 此时求得一组特解(因为 \(exgcd\) 解出的是 \(RHS = gcd\) 时的解,所以需要乘倍数) 2#. \(x = (x \% (k / g) + k / g) % (k / g)\) , 此时求得最小正整数解。 \(\text{TIP : 1. 本题无需开int64 2. 1# 无需加%k}\) 来源: https://www.cnblogs.com/yangxuejian/p/11992466.html

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

匿名 (未验证) 提交于 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

Java中的random函数是如何实现的

允我心安 提交于 2019-11-30 19:43:53
在Java中调用这个Math.Random()函数能够返回带正号的double值,取值范围是[0.0,1.0)的左闭右开区间,返回值是一个 伪随机 选择的数,在该范围内(近似) 均匀分布 。 1. random()函数的使用 Java的API中是这样描述Random()函数的: 伪随机 ,也就是 有规则 的随机,所谓有规则的就是在给定种(seed)的区间内随机生成数字 。 相同种子数的Random对象,相同次数生成的随机数字是完全相同的。 Random类中各方法生成的随机数字都是 均匀分布 的,也就是说区间内部的数字生成的几率均等。 下面是Java.util.Random()方法摘要 protected int next(int bits):生成下一个伪随机数。 boolean nextBoolean():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的boolean值。 void nextBytes(byte[] bytes):生成随机字节并将其置于用户提供的 byte 数组中。 double nextDouble():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布的 double值。 float nextFloat():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布float值。 double

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

这一生的挚爱 提交于 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-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)满足这个方程。