[NOIP提高组]同余方程

题目链接

扩展欧几里得算法

对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by

设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,ab!=0 时

$$ax_1+by_1=\gcd(a,b)$$

 

$$bx_2+(a \mod b)y_2=\gcd(b,a \mod b) $$

因为$\gcd(a,b)==\gcd(b,a \mod b)$

所以$ax_1+by_1=bx_2+(a \mod b)y_2$

$ax_1+by_1=bx_2+(a - \frac{a}{b} \times b )y_2$ 注:这里的a/b 是整除 

$ax_1+by_1 = bx_2+(a \times y_2 - \frac{a}{b} \times b \times y_2 )$

$ax_1+by_1 = a \times y_2 + bx_2 - \frac{a}{b} \times b \times y_2$

所以求出通解

$$ x_1=y_2 $$ 

$$ y_1=x_2 - \frac{a}{b} \times y_2 $$ 

逆元

扩展欧几里得算法有什么用呢? 最大的作用就是求逆元。

什么叫做逆元?

逆元

 这里,我们称 x 是 a 关于 m 的乘法逆元

  这怎么求?首先a必须与m互质(充要条件)  即gcd(a,m)=1 为什么?  因为如果 a可以被m整除的话 那么a mod m必为0

根据gcd(a,m)=1 可以得出 ax+my=1 ,这时候用 扩展欧几里得算法 就可以求出x的值了。

但是 大部分题目要求 x是最小正整数解

这个时候就需要 (x+m)%m了。因为x有可能是负数

证明一下 (x+m)%m  不会证明....

 1 #include <cstdio>
 2 typedef long long ll;
 3 ll a,b,x,y;
 4 ll ex_gcd(ll a,ll b,ll &x,ll &y){
 5     if(!b){
 6         x=1;
 7         y=0;
 8         return a;
 9     }
10     ll ans = ex_gcd(b,a%b,x,y);
11     ll num = x;
12     x = y;
13     y = num - (a/b)*y;
14     return ans;
15 }
16 
17 int main(){
18     scanf("%lld%lld",&a,&b);
19     ex_gcd(a,b,x,y);
20     printf("%lld",(x+b)%b);
21     return 0;
22 }
代码实现

 

转载于:https://www.cnblogs.com/OIerLYF/p/6913733.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值