【洛谷P1516】青蛙的约会

题目大意:给定 \(a,b,c\),求线性同余方程 \(ax+by=c\) 的最小正整数解。

题解:首先判断方程是否有解,若 c 不能整出 a 与 b 的最大公约数,则无解。若有解,则利用扩展欧几里得算法先求出 \(ax'+by'=gcd(a,b)\) 的一组解,再根据倍数进行缩放即可得到原不定方程的一组解。求最小正整数解可以根据公式 \((x\%mod+mod)\%mod\) 得出,原因如下:C++ 负数取模为截断机制,即:不会向下取整,直接进行截断。因此,若 x 为负数,则取模之后会变成绝对值小于 mod 的最大负数,再利用加 mod % mod 即可得出正确结果。另外,对于有解的同余方程的一组通解为 \(x=x_0+{b\over d}*k\)

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll m,n,a,b,L,mod;

ll exgcd(ll a,ll b,ll &x,ll &y){
	if(!b)return x=1,y=0,a;
	ll d=exgcd(b,a%b,x,y),z=x;
	x=y,y=z-a/b*y;
	return d;
}

int main(){y
	ll x,y;
	scanf("%lld%lld%lld%lld%lld",&a,&b,&m,&n,&L);
	if(n>m)swap(m,n),swap(a,b);	
	ll d=exgcd(m-n,L,x,y);
	if((b-a)%d)puts("Impossible");
	else{
		ll mod=L/d;
		printf("%lld\n",(x*(b-a)/d%mod+mod)%mod);
	}
	
	return 0;
}
posted @ 2019-04-17 22:40  shellpicker  阅读(127)  评论(0编辑  收藏  举报