解决乾隆老子的老子遇到的问题

题解:
本题上手就是精密的数学推导+理性分析,过程如下:

设经过a天
那么
(x+am-(y+an))%L=0
(x-y+am-an)%L=0
((x-y)+a*(m-n))%L=0
(x-y)+a*(m-n)=bl;
a*(m-n)-bl=(x-y)

所以,就可以用exgcd求解
显然,若x-y%gcd((m-n),l)!=0,那么同余方程是不成立的,即“Impossible”
接下来求解exgcd((m-n),l,a,b):
即当b!=0时递归求解exgcd(l,(m-n)%l,a,b)

原式为exgcd(a,b,x,y)
变化后即为exgcd(b,a%b,x,y)
a'=b
b'=a%b

那么就可以得到a’*x’+b’*y’=gcd(a,b)的一组特解,即x’,y’
便得到了递归结束后x,y的表达式:

x=y'
y=x'-(a/b)*y'

证明如下:

ax+by=d,bx'+(a%b)y'=d
bx'+(a-a/b*b)y'=d
bx'+ay'-a/b*by'=d
ay'+b(x'-a/b*y')=d
x=y',y=x'-a/b*y'

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll x,y,m,n,l;
ll xx,yy;
ll exgcd(ll a,ll b,ll &xx,ll &yy){
	if(!b){
		xx=1;
		yy=0;
		return a;	
	}
	ll gcd=exgcd(b,a%b,yy,xx);
	yy-=(a/b)*xx;
	return gcd;
}
int main(){
	scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
	ll aa= ((m-n)%l+l)%l;
	ll bb=l;
	ll cc=((y-x)%l+l)%l;
	ll gcd=exgcd(aa,bb,xx,yy);
	ll bg=bb/gcd;
	if(cc%gcd!=0)
		printf("Impossible");
	else{
		ll ans=((xx*(cc/gcd))%bg+bg)%bg;
		printf("%lld",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值