poj1061

本文深入探讨了在模运算环境下解决线性同余方程的方法,通过扩展欧几里得算法找到方程的解。重点介绍了如何将原始方程转化为正整数形式,以及如何利用扩展欧几里得算法求解。此外,文章还详细解释了如何通过模运算调整解的范围,确保其成为正整数解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

program p1061;
var x,y,n,m,l,a,b,d,xx,yy:int64;
function exgcd(a,b:int64;var x,y:int64):int64;
var t:int64;
begin
 if b=0 then
  begin
   x:=1;y:=0;
   exgcd:=a;
  end
 else
  begin
   exgcd:=exgcd(b,a mod b,x,y);
   t:=x;x:=y;y:=t-a div b*y;
  end;
end;
begin
 read(x,y,m,n,l);
 a:=(m-n+l) mod l;
 b:=(y-x+l) mod l;
 d:=exgcd(a,l,xx,yy);
 if b mod d<>0 then
  writeln('Impossible')
 else
  begin
   xx:=(xx*b div d) mod l;l:=l div d;
   if xx<0 then xx:=(xx+l*((-xx) div l+1)) mod l;//!!
   if xx-l>0 then xx:=xx mod l;//!!
   write(xx);
  end;
end.

根据题目可得方程(m-n)xx=(y-x) mod l

令a=m-n,b=y-x要把a,b转换成正整数,在模l下加l即可

a*xx+l*yy=b

如果gcd(a,l)|b,那么方程有解(特别考虑,如果m-n=a=0,gcd(a,l)=l,可以直接判断出来不整除,或者同起点,可以整除)

扩展欧几里德求的是它:a*xx+l*yy=gcd(a,l)的解xx

原方程的解为xx:=xx*(b div gcd(a,l))

这里的转化只是一个可行解,并不一定是最小且是正整数

如果xx<0,不断+l div gcd(a,l)直到变成正的

如果xx>l div gcd(a,l),xx:=xx mod (l div gcd(a,l));

为什么是l div gcd(a,l):把xx=xx*(b div gcd(a,l)),yy=yy*(b div gcd(a,l))带入原方程,两边同时约去b,变成a div gcd(a,l)*xx+l div gcd(a,l)*yy=1,变成了模l div gcd(a,l)下的方程

注意要用if判断是否是上面两种情况,用公式算出结果,否则会超时

不要用while!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值