HELLO WORLD--一起加油(🍺)!|

kingwzun

园龄:3年6个月粉丝:111关注:0

数论 _ 扩展欧几里得算法

裴蜀定理
对于任意正整数a,b, 一定存在整数x, y,使得 ax+by=(a,b)

因为ab为常数,令d=(a,b)
ax+by=d

扩展欧几里得算法就是用于求上面的x和y。
注意:
x和y不唯一。

证明

因为

gcd(a,b)=gcd(b,a%b)

bx+(a%b)y=gcd(b,a%b)

bx+(aa/bb)y=gcd(b,a%b)

ay+b(xa/by)=gcd(b,a%b)=gcd(a,b)

故而

x=y,y=xa/by

因此可以采取递归算法 先求出下一层的x′和y′ 再利用上述公式回代即可。

代码:

#include <iostream>
#include <algorithm>
using namespace std;
int exgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
int n;
scanf("%d", &n);
while (n -- )
{
int a, b;
scanf("%d%d", &a, &b);
int x, y;
exgcd(a, b, x, y);
printf("%d %d\n", x, y);
}
return 0;
}

应用

线性同余方程

axb(modm)
等价于 axmy=b(x,y'是未知数)

y=y,则有 ax+my=b
根据 裴蜀定理,上述等式有解当且仅当 b是gcd(a,m)的倍数。
所以可以用拓展欧几里得算法

代码:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int exgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
int n;
scanf("%d", &n);
while (n -- )
{
int a, b, m;
scanf("%d%d%d", &a, &b, &m);
int x, y;
int d = exgcd(a, m, x, y);
if (b % d) puts("impossible");
else printf("%d\n", (LL)b / d * x % m);
}
return 0;
}

求逆元

本文作者:kingwzun

本文链接:https://www.cnblogs.com/kingwz/p/16627763.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(62)  评论(0编辑  收藏  举报
历史上的今天:
2021-08-26 补题*总结题21/8/26
2021-08-26 c++速成笔记
2021-08-26 数据结构 栈and队列
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起