NOIP2012Day2T1同余方程解题报告以及扩展欧几里得讲解
来源:互联网 发布:知闻视频的tina是谁? 编辑:程序博客网 时间:2024/06/03 19:37
题目描述
求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解。
输入输出格式
输入格式:
输入只有一行,包含两个正整数 a, b,用一个空格隔开。
输出格式:
输出只有一行,包含一个正整数 x0,即最小正整数解。输入数据保证一定有解。
输入输出样例
输入样例#1:
3 10
输出样例#1:
7
说明
【数据范围】
对于 40%的数据,2 ≤b≤ 1,000;
对于 60%的数据,2 ≤b≤ 50,000,000;
对于 100%的数据,2 ≤a, b≤ 2,000,000,000。
NOIP 2012 提高组 第二天 第一题
这是一道数论的题目,首先先说下同余的概念同余的形式就是ax≡kmod(b)他的形式就可以转变为–>ax mod b = k这样子的形式。用集合论的语言,严格地来说就是:
对于整数集的任意一个子集Z,对于任意一个属于Z的元素n,n都除以m,得到的余数可以为0,1,2,…m-1,共m种。我们就以余数的大小作为标准,将Z分为m个互不相交的m个子集Z0,Z1,Z2,…Zm-1。
对于Zi的任意两个元素a,b,都关于m同余。记为
a≡b(mod m)。
我们解同余方程可以用到扩展欧几里得
大概的意思就是如下
int E_gcd(int a,int b,int &x,int &y){ int ret,temp; if(!b){ x=1;y=0; return a; } ret=E_gcd(b,a%b,x,y); temp=x; x=y; y=temp-a/b*y; return ret;}
因为这里我们要对x,y本身进行修改来实现算法本身,所以在对函数本身定义的时候要加上取地址符来时限对x,y值的修改。
那么明白了扩展欧几里得算法本身之后代码本身就很好写了
#include<cstring>#include<cstdio>#include<algorithm>#include<iostream>using namespace std;int a,b,x,y;inline int gcd(int a,int b,int &x,int &y){ if(!b){ x=1,y=0; return a; } int r=gcd(b,a%b,x,y); int temp=x; x=y; y=temp-a/b*y; return r;}int main(){ scanf("%d%d",&a,&b); gcd(a,b,x,y); printf("%d",(x+b)%b);turn 0;}
下面我们来说一下扩展欧几里得
概述
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:
gcd函数就是用来求(a,b)的最大公约数的。
gcd函数的基本性质:
gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)
公式表述
gcd(a,b)=gcd(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
语言实现
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
扩展算法
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然
存在整数对 x,y ,使得 gcd(a,b)=ax+by。
语言实现
int gcd(int a,int b,int &x,int &y){
if (b==0){
x=1,y=0;
return a;
}
int q=gcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
求解 x,y的方法的理解
设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,a>b>0 时
设 ax1+ by1= gcd(a,b);
bx2+ (a mod b)y2= gcd(b,a mod b);
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax1+ by1= bx2+ (a mod b)y2;
即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
根据恒等定理得:x1=y2; y1=x2- [a / b] *y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
扩展欧几里德算法
扩展欧几里德算法是用来在已知a, b求解一组x,y使得ax+by = Gcd(a, b) =d(解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。实现:
int exGcd(int a,int b,int &x,int &y)
把这个实现和Gcd的递归实现相比,发现多了下面的x,y赋值过程,这就是扩展欧几里德算法的精髓。
{
if(b==0)
{
x=1;y=0;
return a;
}
int r=exGcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
return r;
}
可以这样思考:
对于a’=b,b’=a%b 而言,我们求得 x, y使得 a’x+b’y=Gcd(a’,b’)
由于b’=a%b=a-a/b*b (注:这里的/是程序设计语言中的除法)
那么可以得到:
a’x+b’y=Gcd(a’,b’) ===>
bx+(a - a / b * b)y = Gcd(a’, b’) = Gcd(a, b) ===>
ay +b(x - a / b*y) = Gcd(a, b)
因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y)
使用扩展欧几里德算法解决不定方程的办法
对于不定整数方程pa+qb=c,若 c mod Gcd(a, b)=0,则该方程存在整数解,否则不存在整数解。
有种较为不严谨的方法证明,不过至少弥补了一点空白,望某些数论大师补充修改:
由于我们知道,存在一组x与y使得a*x+b*y=gcd(a,b)。
将等式两边同时乘以整数k,即a*x*k+b*y*k=gcd(a,b)*k。如果c mod gcd(a,b)=f,则0<=f
- NOIP2012Day2T1同余方程解题报告以及扩展欧几里得讲解
- PKU1061 解题报告 青蛙的约会 __用扩展欧几里得解模同余方程
- LuoguP1082[NOIP2012] 同余方程 解题报告【拓展欧几里得】
- 同余方程 解题报告
- 1200同余方程{扩展欧几里得}
- exgcd扩展欧几里得--noip同余方程
- noip2012 同余方程 (扩展欧几里得)
- [NOIP 2012]同余方程 扩展欧几里得
- 扩展欧几里得noip2012同余方程
- 同余方程(扩展欧几里得)
- poj 1061 扩展欧几里得求解同余方程
- poj1061_扩展欧几里得_求线性同余方程
- 扩展欧几里得算法解同余方程(NOIP2012)
- nefu84 五指山(扩展欧几里得算法解同余方程)
- [搬运]关于扩展欧几里得与同余方程
- [数论][扩展欧几里得算法][NOIP2012] 同余方程
- 【扩展欧几里得】Codevs 1200: [noip2012]同余方程
- 【NOIP2012】洛谷1082 同余方程 扩展欧几里得详解
- HTTP方法
- bugku xss
- java
- POJ 3977 Subset (简单折半枚举)
- 运行百度地图demo过程及问题
- NOIP2012Day2T1同余方程解题报告以及扩展欧几里得讲解
- python爬虫——用selenium和phantomjs对新浪微博PC端进行爬取(二)
- Dubbo+Zookeeper+Spring mvc+Nginx 集群负载均衡 详细demo
- 解读Batch Normalization
- makefile:2: *** missing separator. Stop. make 之后出现的错误,解决方法
- 关于python中phantomjs无法访问网页的处理
- (一) MySQL 性能优化 基础之索引概念
- (二) MySQL 优化
- HBase CURD之Get