数论学习笔记之解线性方程 a*x + b*y = gcd(a,b)

~》》_《《~

咳咳!!!今天写此笔记,以防他日老年痴呆后不会解方程了!!!

  Begin !

~1~, 首先呢,就看到了一个 gcd(a,b),这是什么鬼玩意呢?什么鬼玩意并不重要,重要的她代表的含义,其实呢,gcd(a,b)就表示 非负整数 a 和 b(不同时为0) 的最大公约数,(数论概论上说:计算 a 与 b 的最大公因数的更低效方法是我女儿四年级老师教的方法,老师要求学生求出 a 与 b 的所有因数,然后找出同时出现在两个表中的最大数字。 YES!A good idea for 小学生!) 。如今呢,我们自然不能这样算啦!

好吧!从求 gcd (a,b) 开始!

  一般的有下列式子:

a = b * q1 + R1  ;

b = R1 *q2 + R2 ;

R1 = R2 * q3 + R3 ;

R2 = R3 * q4 + R4 ;

。。。。。。

。。。。。。

  这样写下去什么时候才是个头啊~_~。。。

  很显然 必然会有结束的地方的,因为肯定会有一个 R  为 0 (R2 >= R4 >= R6 ....,R1 >= R3 >= R5 ...),好吧,继续往下写:

Rn-1 = Rn * qn+1  +   Rn+1  ;

Rn = Rn+1 * qn+2  +  Rn+2 ;假设 Rn+2 == 0

。。。。。。。。。。。。。 ok!^_^  。。。。。。。。。。。。。。

Rn+2 = 0了,那么由最后一个式子得 Rn+1整除Rn,接着,Rn+1 整除 Rn-1,,,,很显然的,这个递推可以推到第一个式子,so,Rn+1 整除 a,Rn+1 整除 b, 也就是说 Rn+1 是 a 与 b 的公约数了,是不是最大的呢?先把 Rn+1 记为 g,设 d 为 a 与 b  的任意一个公约数,由第一个

式子(a = b * q1 + R1)可以知道,d 整除 R1 ,再代入到第二个式子里得, d 整除 R2,推啊推,推啊推,最后知道了 d 整除 Rn+1,即 d 整除 g,

因为 d 是任意的公约数 , d 整除 g ,那么 取 d 为 最大公约数,则 g 既是公约数,又是最大公约数的倍数,只能是 :g 就是最大公约数。

  在前面“,,,,递推 。。”里隐藏了一个惊天大秘密,那就是 gcd(a,b) = gcd(b,a%b),这个秘密啊,十分的奇妙!为啥有这个结论呢?从第一个式子(a = b * q1 + R1) 显然, gcd (a,b) = g; 再显然 gcd(b,r1) = g ; 。。。。。 显然嘛,gcd (a,b) = gcd(b,a%b),

 。。。。。。。。。。。ok。这个问题算是解决了。代码附上。。。。。。。。。。。。。。。。。。。

1 int gcd(int a,int b)
2 {
3     return b==0?a:gcd(b,a%b) ;
4 }

gcd

~2~,好吧,其实前面只是闲扯!不过我可以赌五毛钱前面的东西没有偏题!

  下面来正面解决这个问题:a*x + b*y = gcd(a,b) ;

  一般的有下列式子:

a = b * q1 + R1  ;     R1 = a - q1 * b ;

b = R1 *q2 + R2 ;    R2 = b - q2 * R1 ;

R1 = R2 * q3 + R3 ;   R3 = R1 - q3 * R2 ;

R2 = R3 * q4 + R4 ;

。。。。。。

  值得注意的是右边的式子。可以发现每一个 R 都可以表示成 a 和 b 的倍数(把R1记作 (1,-q1)),可以定义一个结构体 A, B(好吧,是两个),

A.x ,A.y 分别表示 a, b 的系数,初始化一下A = a = (1,0),B = b = (0,1), 那么,R1 = A - q1*B ; 可以看到下面还要用到R1,而且用不到 A 了,

直接 令 A = R1 多好呢! A = A - B*q1 ; 再看R2 , R2 = B - q2*R1 = B - q2*A ; 同样 令 B = R2;则 B = B - A*q2;下面 R3 = A - q3*B ;也就是

A = A - q3*B ;再接着: B = B - A*q 。。。。。。等等,什么时候终止呢?在“再看R2"之前,考虑这样一个问题,若 R1 == g 呢?显然这个时候就要终止了,伪代码如下:

while(1) {

  q = a/b;

  r = a%b;

  A = A - B*q;

  (a,b) = (b,a%b);

  (A,B) = (B,A) //这样更容易写代码

  if (a%b == 0) break;

}

: 0 需特判。

代码如下:

 1 void sol(int a,int b,int &g)
 2 {
 3     A.x = B.y = 1 ;
 4     A.y = B.x = 0 ;
 5     if (a == 0) {
 6         g = b ;
 7         A.x = 1;
 8         A.y = 0;
 9         return ;
10     }
11     if (b == 0) {
12         g = a;
13         A.x = 0;
14         A.y = 1;
15         return ;
16     }
17     Node C ;
18     int q, r ;
19     while (1) {
20         q = a/b ;
21         r = a%b ;
22         A.x = A.x - B.x*q;
23         A.y = A.y - B.y*q;
24         a = b;
25         b = r;
26         if (a%b == 0) break;
27         C = A;
28         A = B;
29         B = C;
30     }
31     g = b ;
32 }

ex_gcd

~3~。未完待续。

时间: 2024-12-18 07:11:28

数论学习笔记之解线性方程 a*x + b*y = gcd(a,b)的相关文章

数论学习笔记

素数: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int p[10000000],a[100000001]; int main() { int i,t=0,j,n; scanf("%d",&n); a[1]=1; for (i=2;i<=n;++i) { if (!a[i]) p[++t]=i; for (j=1;j<=t&

ES6-个人学习笔记二--解构赋值

第二期,解构赋值如果能够熟练应用确实是个十分方便的功能,但是过分的依赖和嵌套只会让代码理解和维护起来十分困难,是个体现高逼格的表达式呢~ 1,解构赋值的基础 //定义:es6运行按照一定模式,从数组或对象中提取值,并对变量进行赋值,如 var [a,b,c] = [1,2,3]; //一些其他方式 let [ , , a1] = [1,2,3]; //a1:3 let [a2,...b2] = [1,2,3,4]; //a2:1,b2:[2,3,4] let [a3,b3,...c3] = [1

JMeter学习笔记--详解JMeter逻辑控制器

JMeter使用逻辑控制器来决定采样器的处理顺序 简单控制器(Simple Controller):存储设备(将某些采样器归组) 循环控制器(Loop Controller:设置循环次数 仅一次控制器(Once Only Controller) 交替控制器(Interleave Controller) 随机控制器(Random Controller) 随机顺序控制器(Random Order Controller): 每个子测试元件都至多执行一次,但是执行顺序是随机的 吞吐量控制器(Throug

RabbitMQ学习笔记2-理解消息通信

消息包含两部分:1.有效载荷(payload) - 你想要传输的数据.2.标签(lable) - 描述有效载荷的相关信息,包含具体的交换器.消息的接受兴趣方等. rabbitmq的基础流程如下: RabbitMQ的客户端和服务端通过channel与RabbitMQ服务器进行通信. Channel(信道):程序和RabbitMQ之间的连接是通过channel,channel是基于TCP协议之上的?, 一个TCP连接可以有多个channel,可以比喻成如下:一根大电缆里面有很多根小的电线,大电缆就是

JMeter学习笔记--详解JMeter配置元件

JMeter配置元件可以用来初始化默认值和变量,以便后续采样器使用.将在其作用域的初始化阶段处理. CSV Data Set Config:被用来从文件中读取数据,并将它们拆分后存储到变量中,适合处理众多变量 Variable Names:变量名列表(逗号分隔).JMeter2.3.4以后的版本,支持CSV标题行,如果变量名为空,那么文件的第一行将被读取,并被解释为列名的列表.这些变量名必须使用分割符加以区分,他们可以使用双引号加以引用.默认情况下,该文件仅打开一次,而每个线程会使用文件中不同的

C#学习笔记--详解委托,事件与回调函数

.Net编程中最经常用的元素,事件必然是其中之一.无论在ASP.NET还是WINFrom开发中,窗体加载(Load),绘制(Paint),初始化(Init)等等.“protected void Page_Load(object sender, EventArgs e)”这段代码相信没有人不熟悉的.细心一点一定会发现,非常多的事件方法都是带了“object sender, EventArgs e”这两个参数.这是不是和委托非常相似呢? 一.委托(有些书中也称为委派) 委托是什么呢?这个名字的意思已

JMeter学习笔记--详解JMeter定时器

定时器的处理优先于同一作用域内的采样器,如果在同一作用域内有多个定时器,那么所有的定时器都会在每个采样器之前处理. 若定时器所在作用域内无采样器,那么定时器不会被处理 固定定时器,每个线程在请求之间间隔固定时长 Gaussian Random Timer: 会暂停每个线程请求一个随机时长,而大多数时间间隔接近于一个固定值 Uniform Random Timer:会暂停每个线程请求一个随机时长,每个时间间隔都有同样的出现几率 Constant Throughput Timer:可变暂停时长,通过

Linux 程序设计学习笔记----终端及串口编程基础之概念详解

转载请注明出处,谢谢! linux下的终端及串口的相关概念有: tty,控制台,虚拟终端,串口,console(控制台终端)详解 部分内容整理于网络. 终端/控制台 终端和控制台都不是个人电脑的概念,而是多人共用的小型中型大型计算机上的概念. 1.终端 一台主机,连很多终端,终端为主机提供了人机接口,每个人都通过终端使用主机的资源. 终端有字符哑终端和图形终端两种. 控制台是另一种人机接口, 不通过终端与主机相连, 而是通过显示卡-显示器和键盘接口分别与主机相连, 这是人控制主机的第一人机接口.

【转】TCP/IP详解学习笔记(二)

TCP/IP详解学习笔记(5)-IP选路,动态选路,和一些细节 1.静态IP选路 1.1.一个简单的路由表 选路是IP层最重要的一个功能之一.前面的部分已经简单的讲过路由器是通过何种规则来根据IP数据包的IP地址来选择路由.这里就不重复了.首先来看看一个简单的系统路由表. Destination     Gateway         Genmask         Flags Metric Ref    Use Iface192.168.11.0    *               255.