欧几里德定理:

对于整数a,b来说,gcd(a, b)==gcd(b, a%b)==d(a与b的最大公约数),又称为辗转相除法

证明:

因为a是d的倍数,b是d的倍数;所以a%d==0;b%d==0;

设k=a/b;r=a%b;则 a=k*b+r;

由上得出:r=a-k*b;

因为a和b都是d的倍数,所以(a-k*b)也是d的倍数,所以r也是d的倍数;

所以gcd(a, b)==gcd(b, a%b)==d

而为什么要证明gcd(a, b)==gcd(b, a%b)==d这个式子成立呢?

其实证明gcd(a, b)==gcd(a, a%b)==d这个式子成立也是可以的,因为a也是d的倍数,但是在进行递归之前要进行一步操作,就是判断a与b的大小,如果a<b,就没办法进行递归或者循环求最大公约数,那么如果a<b,就交换a与b,之后就不用交换了,因为已知a>b,那么a%b<a必定成立;

事实发现证明gcd(a, b)==gcd(b, a%b)==d这个式子会缩小处理的数据的范围;

欧几里德应用:

用来求a,b的最大公约数。

代码实现:

//gcd(a, b)==gcd(a, a%b)==d,也成立
#include<stdio.h>
int main()
{
int m, n, r, t;
scanf("%d%d", &m, &n);
if(m<n)
{
t=m;
m=n;
n=t;
}
while(r=m%n, r!=0)
{
m=m;
n=r;
}
printf("%d\n", n);
return 0;
}

  

//gcd(a, b)==gcd(a, a%b)==d递归
int gcd(int m, int n)
{
return n?gcd(n, m%n):m;
}

  

//gcd(a, b)==gcd(a, a%b)==d递归
int gcd(int m, int n)
{
if(m%n==0)
return n;
else
return gcd(n, m%n);
}

  

//gcd(a, b)==gcd(b, a%b)==d 循环
while((r=m%n)!=0)
{
  m=n;
  n=r;
}

扩展欧几里德定律: 

对于不完全为0的非负整数a,b;gcd(a, b)表示a, b的最大公约数,必定存在整数对x,y,满足a*x+b*y==gcd(a, b);

证明:

a*x1+b*y1=gcd(a, b); 

b*x2+(a%b)*y2=gcd(b, a%b);

因为由欧几里德定理知:gcd(a, b)==gcd(b, a%b)

所以a*x1+b*y1=b*x2+(a%b)*y2;     因为r=a%b,   r =a-k*b所以==>

a*x1+b*y1=b*x2+(a-k*b)*y2;         因为k=a/b;所以 ==>

a*x1+b*y1=b*x2+(a-(a/b)*b)*y2;     展开得到  ==>    

a*x1+b*y1=b*x2+a*y2-b*(a/b)*y2;  转换得到      ==>

a*x1+b*y1=a*y2+b*(x2+(a/b)*y2);

观察上式可知 x1=y2, y1=x2-a/b*y2;

由此可知x1,y1是由x2,y2得出来的,由此类推x2,y2是由x3,y3得出来的,

那什么时候是终止呢?也就是递归gcd(a, b)中b=0时;也就是说此时a的值就是要求得最大公约数

即gcd(a, 0)此时由扩展欧几里得定律a*x+b*y==gcd(a, b)知 a*x+b*y=a;

解出x=1, y=0;

此时就是递归终止的地方:

扩展欧几里德应用:

就我目前所知的就是:求解不定方程;如a*x+b*y=c; 已知a, b, c的值求x和y的值

那么问题来了,如何将扩展欧几里德定律应用在求解不定方程呢?

可以这样转化   a*x+b*y=gcd(a, b)*c/gcd(a, b);

最后转化为 a*x/(c/gcd(a, b))+b*y/(c/gcd(a, b))=gcd(a, b); 最后求出的解x0,y0乘上c/gcd(a, b)就是最终的结果了

x1=x0*c/gcd(a, b);

y1=y0*c/gcd(a, b);

代码实现:  举例说明:http://codeforces.com/problemset/problem/7/C

#include<stdio.h>
long long exgcd(long long a, long long b, long long &x, long long &y);
int main()
{
long long a, b, c, ans, x, y; while(scanf("%lld%lld%lld", &a, &b, &c)!=EOF)
{
ans=exgcd(a, b, x, y);
if(c%ans==0)
{
x=-x*c/ans;
y=-y*c/ans;
printf("%lld %lld\n", x, y);
}
else
printf("-1\n");
}
return 0;
}
long long exgcd(long long a, long long b, long long &x, long long &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
long long r=exgcd(b, a%b, x, y), t;
t=x;
x=y;
y=t-(a/b)*y;
return r;
}

 但这只是求得了一组解x1,y1

对于x,y对应的解集是:

x=x1+b/gcd(a, b)*t;

y=y1-b/gcd(a, b)*t;

但是我证明不出来,如果哪位大神懂得,可以给我说说!

欧几里德和扩展欧几里德详解 以及例题CodeForces 7C的更多相关文章

  1. 开启PHP exif扩展方法详解

    服务器配置说明: 1.在php.ini文件中找到;extension=php_exif.dll,去掉前面的分号2.在php.ini文件中找到;extension=php_mbstring.dll,去掉 ...

  2. SpringBoot各类扩展点详解

    一.前言 上篇文章我们深入分析了SpringBoot的一站式启动流程.然后我们知道SpringBoot的主要功能都是依靠它内部很多的扩展点来完成的,那毋容置疑,这些扩展点是我们应该深入了解的,那么本次 ...

  3. BSGS算法_Baby steps giant steps算法(无扩展)详解

    Baby Steps-Varsity Giant Step-Astronauts(May'n・椎名慶治) 阅读时可以听听这两首歌,加深对这个算法的理解.(Baby steps少女时代翻唱过,这个原唱反 ...

  4. 欧几里德与扩展欧几里德算法 Extended Euclidean algorithm

    欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd( ...

  5. 中国剩余定理(CRT)及其扩展(EXCRT)详解

    问题背景   孙子定理是中国古代求解一次同余式方程组的方法.是数论中一个重要定理.又称中国余数定理.一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作<孙子算经>卷下第 ...

  6. BIT 树状数组 详解 及 例题

    (一)树状数组的概念 如果给定一个数组,要你求里面所有数的和,一般都会想到累加.但是当那个数组很大的时候,累加就显得太耗时了,时间复杂度为O(n),并且采用累加的方法还有一个局限,那就是,当修改掉数组 ...

  7. [转]用C/C++扩展PHP详解

    原文:http://www.imsiren.com/archives/547 一个简单的扩展模块 PHP非常容易扩展,因为它提供了我们想用的所有API. 如果要新建一个扩展,需要在PHP源码中执行ex ...

  8. artDialog学习之旅(二)之扩展方法详解

    名称 描述 核心方法 art.dialog.top 获取artDialog可用最高层window对象.这与直接使用window.top不同,它能排除artDialog对象不存在已经或者顶层页面为框架集 ...

  9. C#中的扩展方法详解

    “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.”这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些类 ...

随机推荐

  1. JavaBean入门及简单的例子

    不会编写JavaBean就不是一个Java开发人员. 那么,何谓JavaBean呢? JavaBean是符合某种规范的Java组件,也就是Java类. 它必须满足如下规范: 1)必须有一个零参数的默认 ...

  2. bootstrap之按钮和图片

    一.按钮 类 描述 .btn 为按钮添加基本样式 .btn-default 默认/标准按钮 .btn-primary 原始按钮样式(未被操作) .btn-success 表示成功的动作 .btn-in ...

  3. navigater导航

    1.css的hover事件2.url事件(或者click事件),激活当前项3.第一导航与第二导航的移入移出事件(可以通过left,top值来显示,也可以变化宽度,高宽来显示)4.有二级导航的另外给cl ...

  4. 一、微信小游戏开发 --- 初次在微信开发者工具里跑Egret小游戏项目

    尝试下Egret的小游戏开发,学习,学习,干IT,不学习,就得落后啊... 相关教程: Egret微信小游戏教程 微信公众平台-微信小游戏教程 微信公众平台-微信小游戏接入指南 开发版本: Egret ...

  5. wamp安装和基础配置

    一 下载地址 二 安装 三 修改默认网站目录 四 修改数据库密码 一 下载地址 wamp百度软件中心 wamp官方下载地址 二 安装 windows环境下wampserver的配置教程——超级详细 w ...

  6. 【Android】保存Bitmap到SD卡

    1.打开读写SD卡的权限 需要在AndroidManifest.xml加入如下代码: <uses-permission android:name="android.permission ...

  7. UUID的定义以及作用

    UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OS ...

  8. Centos6.5安装JDK环境

    1,系统版本查看 2,下载jdk1.8 wget http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c ...

  9. 巧用Salt,实现CMDB配置自动发现

    随着互联网+新形势的发展,越来越多的企业步入双态(稳敏双态)IT时代,信息化环境越来越复杂,既有IOE三层架构,也有VCE.Openstack等云虚拟化架构和互联网化的分布式大数据架构.所以,企业急需 ...

  10. python 面向对象 字典 有序字典

    和原来字典一模一样 把dict 传进去 相当于这个类就是一个字典 # 把dict 传进去 相当于这个类就是一个字典 class Mydict(dict): pass d = Mydict() prin ...