题解:本题主要考查扩展欧几里得定理。
简要题意:求
a
x
≡
1
(
m
o
d
b
)
a x \equiv 1 \pmod {b}
ax≡1(modb)最小正整数解
1.扩展欧几里得定理:
a
x
≡
1
(
m
o
d
b
)
a x \equiv 1 \pmod {b}
ax≡1(modb),等价与
a
∗
x
+
m
∗
y
=
1
a*x+m*y=1
a∗x+m∗y=1 ,
因为裴蜀定理
a
x
+
b
y
=
z
,
则
g
c
d
(
a
,
b
)
∣
z
ax+by=z,则gcd(a,b)|z
ax+by=z,则gcd(a,b)∣z 则
g
c
d
(
a
,
b
)
=
1
;
gcd(a,b)=1;
gcd(a,b)=1;
又因为
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
gcd(a,b)=gcd(b,a\mod b)
gcd(a,b)=gcd(b,amodb)所以
b
∗
x
1
+
(
a
m
o
d
b
)
∗
y
1
=
g
c
d
;
b*x_1+(a\mod b)*y_1=gcd;
b∗x1+(amodb)∗y1=gcd;
又因为
a
m
o
d
b
=
a
−
(
a
/
b
)
∗
b
;
a\mod b=a-(a/b)*b;
amodb=a−(a/b)∗b;
所以
b
∗
x
1
+
(
a
−
(
a
/
b
)
∗
b
)
∗
y
1
b*x1 + (a-(a/b)*b)*y1
b∗x1+(a−(a/b)∗b)∗y1
=
b
∗
x
1
+
a
∗
y
1
–
(
a
/
b
)
∗
b
∗
y
1
= b*x1+a*y1–(a/b)*b*y1
=b∗x1+a∗y1–(a/b)∗b∗y1
=
a
∗
y
1
+
b
∗
(
x
1
–
a
/
b
∗
y
1
)
=
g
c
d
= a*y_1 + b*(x1 – a/b*y1) = gcd
=a∗y1+b∗(x1–a/b∗y1)=gcd
所以
x
=
y
1
,
y
=
x
1
–
a
/
b
∗
y
1
;
x=y_1,y=x1 – a/b*y1;
x=y1,y=x1–a/b∗y1;
因此到最后,如果
x
x
x太小就不断加
b
b
b直到大于等于
0
0
0,太大则一直减
b
b
b,直到最小正整数解。直接求模实现更快。
(其实暴力也可,亲测70分QwQ)
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
long long a,b,x,xx,y;
void exgcd(long long a,long long b)
{
if(b==0)
{
x=1;y=0;
return ;
}
exgcd(b,a%b);
xx=x;x=y;y=xx-(a/b)*y;
return ;
}
int main()
{
ios::sync_with_stdio(false);
cin>>a>>b;
exgcd(a,b);
cout<<(x+b)%b;
return 0;
}