题目描述
求关于 xx 的同余方程 a x \equiv a \pmod {1}ax≡a(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;
}