[23] Vijos P1781 同余方程(数论)

P1781同余方程
Accepted
标签: 数论 NOIP提高组2012

描述

求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解。

格式

输入格式

输入只有一行,包含两个正整数a, b,用一个空格隔开。

输出格式

输出只有一行,包含一个正整数x0,即最小正整数解。输入数据保证一定有解。

样例1

样例输入1[复制]

3 10

样例输出1[复制]

7

限制

每个测试点1s

提示

对于40%的数据,2 ≤b≤ 1,000; 
对于60%的数据,2 ≤b≤ 50,000,000; 
对于100%的数据,2 ≤a, b≤ 2,000,000,000。

来源

Noip2012提高组复赛Day2T1

思路

同余方程
在每一类下的任意两个数a,b都关于m同余。记为:
a≡b(mod m)
用集合论的语言,严格地来说就是:
对于整数集的任意一个子集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)

扩展欧几里德
基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by

使用扩展欧几里德算法解决不定方程的办法:

  对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
  上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(p, q)的一组解p0,q0后,p * a+q * b = Gcd(p, q)的其他整数解满足:
  p = p0 + b/Gcd(p, q) * t 
  q = q0 - a/Gcd(p, q) * t(其中t为任意整数)
  至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。

  在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,应该是得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),

  p * a+q * b = c的其他整数解满足:

  p = p1 + b/Gcd(a, b) * t
  q = q1 - a/Gcd(a, b) * t(其中t为任意整数)
  p 、q就是p * a+q * b = c的所有整数解。


代码

#include 
using namespace std;
int a,b,x,y;
void exgcd(int a,int b,int &x,int &y)//扩展欧几里德 
{
	if(!b)
	{
		x=1;
		y=0;
	}
	else
	{
		exgcd(b,a%b,y,x);
		y-=a/b*x;
	}
}
int main()
{
	cin>>a>>b;
	exgcd(a,b,x,y);
	cout<<(x+b)%b;
	return 0;
}
NOIP做题记录(提高组) 





你可能感兴趣的:(数论)