[洛谷]P1082 同余方程 (#数学 -2.1)

题目描述

求关于 xx 的同余方程 a x \equiv a \pmod {1}axa(mod1) 的最小正整数解。

输入输出格式

输入格式:

一行,包含两个正整数 a,ba,b ,用一个空格隔开。

输出格式:

一个正整数 x_0x0 ,即最小正整数解。输入数据保证一定有解。

思路

一道模板题。

首先对于ax ≡ 1 (mod b); 观察数据范围可以发现b≥2,所以转化成 ax mod b=1。从mod的定义中我们可以看出原方程就是ax-by=1(y是整数)

因为一定有解,然后由裴蜀定理可以知道gcd(a,b)|1,即gcd(a,b)=1,得证a,b互质。

//拓展欧几里德
1.求解不定方程a*x+b*y==gcd(a,b);
先给个解法推导吧:
∵a=[a/b]*b+a%b;
又∵欧几里得知:gcd(a,b)==gcd(b,a%b);
∴([a/b]*b+a%b)*x+b*y=gcd(a,b);
∴[a/b]*b*x+(a%b)*x+b*y=gcd(a,b);
∴b*([a/b]*x+y)+(a%b)*x=gcd(b,a%b);
看到这里,我们不难发现:
令:a'=b,x'=[a/b]*x+y,b'=a%b,y'=x;
整理后原式又变成了:a'*x'+b'*y'==gcd(a',b');
当当当当!!!!!可以递归了,求最小解代码见下:
#define ll long long
........
void ogcd(ll a,ll b,ll &x,ll &y){
if(!b) x=1,y=0;
else{
    ogcd(b,a%b,y,x);
    y-=(a/b)*x;
}
}
当然解虽然最小,有可能是负数,所以只要加个b/gcd(a,b)再模上b/gcd(a,b)就行了; 
2.同余方程ax≡b(mod c)的求解:
   (1)有解条件:
       当且仅当:gcd(a,c)|b;(懒得证了)
       即:b能被gcd(a,c)整除;
   (2)例:洛谷1082 同余方程ax≡1(mod b):
      分析:
      先根据有解的必要条件,显而易见:
        gcd(a,b)|1  ==>  gcd(a,b)==1;
      题目给的a,b一定互质;
      再化开:(a*x)%b==1%b
         ==>  (a*x-1)%b==0
         ==>  a*x==k*b+1  (k∈Z)
         ==>  a*x-k*b==1
         ==>  a*x-k*b==gcd(a,b)
      是不是和上面的1.一样了?

上面两段代码框是转载的。

#include <cstdio>
#include <iostream>
using namespace std;
void ogcd(long long a,long long b,long long &x,long long &y)
{
	if(!b) x=1,y=0;
	else
	{
		ogcd(b,a%b,y,x);
		y-=(a/b)*x;
	}
}
int main()
{
	long long a,b,x,y;
	scanf("%lld%lld",&a,&b);
	ogcd(a,b,x,y);
	printf("%lld",(x+b)%b);
	return 0;
}


猜你喜欢

转载自blog.csdn.net/apro1066/article/details/80531650