Luogu P1082 同余方程

Luogu P1082 同余方程

扩展欧几里得

本题良心题解

code:

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
#define ll long long

ll a,b,x,y;

void exgcd(ll aa,ll bb)
{
	if(bb==0)
	{
		x=1;
		y=0;
		return ;
	}
	exgcd(bb,aa%bb);
	ll t1=x;
	x=y;
	y=t1-(aa/bb)*y;
}

int main()
{
	scanf("%lld %lld",&a,&b);
	exgcd(a,b);
	printf("%lld",(x%b+b)%b);
}

来源:https://www.luogu.org/blog/cicos/solution-p1082
图片来源:https://www.luogu.org/blog/cicos/solution-p1082


扩欧复述:

裴蜀定理:
存在x,y使得a,b满足ax+by=m.
a,b,x,y都是整数,且m一定是gcd(a,b)的倍数

普通的gcd:
求aa和bb的最大公约数
int gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}

当找到最后,b==0时,a就是最大公约数了,我们叫此时的b为b1,a为a1
满足 a1 * x1+b1 * y1=gcd(a1,b1)=gcd(aa,bb)=a,
显然此时x1=1,y1=0

但是a1不是aa,b1也不是bb
那如果要求aa * xx+bb * yy=m呢
先求aa * xx+bb * yy=gcd(aa,bb)吧
我们可以从现在的a1,b1,递归回aa,bb

假设当前我们在求a2和b2的最大公约数,
而我们已经求出了下一个状态:b2和a2%b2的最大公因数,
并且求出了一组x2和y2使得
b2 * x2+(a2 % b2) * y2=gcd
把a2 % b2=a2-a2 / b2 * b2(这个除向下取整哈) 代入上一行的式子
b2 * x2 + (a2-(a2/b2)b2) * y2
=b2 * x2+a2
y1-(a2/b2)b2 * y2
=a2 * y2+b2
(x2-a2/b2 * y2)=gcd
发现 新的x=y2, 新的y=x2-a / b * y2

这就是相邻两层递归状态x,y转化的式子

求出了aa * xx+bb * yy=gcd(aa,bb)的一组解之后
aa * xx+bb * yy=m的一组解 就是xx * [m/gcd(aa,bb)]和yy * [m/gcd(aa,bb)]

对于ax+by=m:
gcd=gcd(a,b);
已经跑了exgcd后
((x*(m/gcd))%(b/gcd)+(b/gcd))%(b/gcd) (求x最小解的式子)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值