解同余式的最小解

  我们知道欧几里得扩展定理是同余方程ax≡b(mod c)解得有力方法。这个方程可能有解也可能没有解,下面给出有解的条件:

  定理:同余方程ax≡b(mod c)有解,当且仅当gcd(a,c)|b,且方程有gcd(a,c)个解。

  原因是求ax≡b(mod c)可以转化为求ax+cy=b。

  令:d=gcd(a,c),  k=c/d;

  我们可以用扩展欧几里得求出x,y值。那么方程ax≡b(mod c)的一个特解:x0=x*(b/d)%c。并且它的d个解分别为:

  Xi=(x0+i*(k))%c,{i=0,1,2,.....d-1}。

  方程ax≡b(mod c)的最小解为:(x0%k+k)%k。

代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 using namespace std;
 5
 6 __int64 Exgcd(__int64 a, __int64 b, __int64 &x, __int64 &y)
 7 {
 8     if(b==0)
 9     {
10         x=1, y=0;
11         return a;
12     }
13     __int64 r = Exgcd(b, a%b, x, y);
14     __int64 tp=x;
15     x = y;
16     y = tp-a/b*y;
17     return r;
18 }
19
20 // ax==b(mod c)
21 void Liner_modu(__int64 a, __int64 b, __int64 c)
22 {
23     __int64 x, y, ans;
24     __int64 d = Exgcd(a, c, x, y);
25     if(b%d)
26     {
27         puts("No solution");
28         return;
29     }
30     ans = x*(b/d)%c;  //特解
31     y = c / d;
32     ans = (ans%y+y)%y; //最小解
33     printf("%I64d\n", ans);
34 }
35 int main()
36 {
37     __int64 a, b, c;
38     while(~scanf("%I64d%I64d%I64d", &a, &b, &c))
39     {
40         while(a<0) a+=c;
41         while(b<0) b+=c;
42         Liner_modu(a, b, c);
43     }
44     return 0;
45 }
时间: 2024-08-02 02:21:56

解同余式的最小解的相关文章

解同余式ax ≡ c(mod m)

将式子变形为 ax-c=my 可以看出原式有解当且仅当线性方程ax-my=c有解 设g = gcd(a, m) 则所有形如ax-my的数都是g的倍数 因此如果g不整除c则原方程无解. 下面假设g整除c: 利用扩展欧几里得算法解出 au + mv =g 一个特解(u0, v0) 所以可用整数c/g乘上上式 au0*(c/g) + mv0*(c/g) = c 得到原式的解x0 = u0*(c/g) 解的个数: 假设x1是ax ≡ c(mod m)的其他解 ax1 ≡ ax2(mod m),所以m整除

Baby_Step,Gaint_Step(分析详解+模板)

以下是总结自他人博客资料,以及本人自己的学习经验. [Baby_Step,Gaint_Step定义] 高次同余方程.   BL == N (mod P) 求解最小的L.由于数据范围很大,暴力不行 这里用到baby_step,giant_step算法.意为先小步,后大步. 令L=i*m+j  (m=ceil(sqrt(p-1))), 那么原式化为 B^(i*m)*B^j==N(MOD P)---->B^j===N*B^(-i*m)(MOD P) 我们先预处理B^0,B^1,B^2--B^(m-1)

Baby_Step,Gaint_Step(分析具体解释+模板)

下面是总结自他人博客资料.以及本人自己的学习经验. [Baby_Step,Gaint_Step定义] 高次同余方程. BL == N (mod P) 求解最小的L.因为数据范围非常大,暴力不行 这里用到baby_step,giant_step算法.意为先小步.后大步. 令L=i*m+j  (m=ceil(sqrt(p-1))), 那么原式化为 B^(i*m)*B^j==N(MOD P)---->B^j===N*B^(-i*m)(MOD P) 我们先预处理B^0,B^1,B^2--B^(m-1),

Uva 11388 GCD LCM ( 数论 )

Uva  11388 GCD LCM( 数论 ) 题意: 求是否存在a,b 使得lcm(a,b) = L, gcd(a,b) = G,不存在输出-1,存在输出a,b,且a尽可能小 分析: 强行暴力是不可能的数据很大,要用llu,这里有两种思路 思路一: 由题意可知 a*b = G*L 保证a = G的倍数的情况下,枚举a再判断G*L能否整除a,最后判断b是否为a的倍数.a从G开始扫到sqrt(G*L) //输入两个整数G,L //找出a,b 使得 gcd(a,b) = G lcm(a,b) =

【程序员的数学思维修炼】总结一

第一章 数据的表示 主要学习了会了 0 不是什么都没有,比如在java里BigDecimal里面是根据最高的那个精度来的,比如1.99+0.01=2.00 这时候提交可能会判错,所以要去掉后导零 为啥要用二进制 还有哪些进制,神奇的八卦,八进制.钟表使用的十二进制.半斤八两十六进制.60年一个甲子六十进制 关于二进制,最主要的是要熟练掌握位运算!一些做题中常用的技巧,比如求n的m次方,判断奇偶,统计一的个数, 这一章里还提到了20!阶乘问题,还记得怎么解决大数阶乘吗. 第二章 神奇的素数 1.验

poj_2115C Looooops(求逆元)

题目链接:http://poj.org/problem?id=2115 C Looooops Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22912   Accepted: 6293 Description A Compiler Mystery: We are given a C-language style for loop of type for (variable = A; variable != B; vari

【转载】学习总结:初等数论(3)——原根、指标及其应用

写得太好了..忍不住转载啊.. 未授权,侵权删. 原博文链接:http://blog.163.com/[email protected]/blog/static/172279052201641935828402/ --------------------------------------------------------------------------------- 学习总结:初等数论(3)——原根.指标及其应用 最近知道了一本书叫<数论概论(第3版)>(A Friendly Intr

【转】初等数论 ——原根、指标及其应用

转自:http://blog.163.com/[email protected]/blog/static/172279052201641935828402/ 学习总结:初等数论(3)——原根.指标及其应用 2016-05-19 15:58:28|  分类: 信息学——学习总 |  标签:初等数论  数学  |举报|字号 订阅 学习总结:初等数论(3)——原根.指标及其应用 最近知道了一本书叫<数论概论(第3版)>(A Friendly Introduction to Number Theory

uva 1368 - DNA Consensus String(字符串处理)

uva 1368 - DNA Consensus String Figure 1. DNA (Deoxyribonucleic Acid) is the molecule which contains the genetic instructions. It consists of four different nucleotides, namely Adenine, Thymine, Guanine, and Cytosine as shown in Figure 1. If we repre