Solution 青蛙的约会
题目大意:求解不定方程\(ax+by=c\)
分析:我们可以把原来的同余式子写成一个不定方程,这部分基本操作不讲,主要讲方程求解。看到不定方程我们就想到\(exgcd\)对吧?
但是\(exgcd\)只能适用于求解\(ax+by=g\),其中\(g=gcd(a,b)\)的情况
我们设\(exgcd\)求出的一组特解是\((x_0,y_0)\),显然对于方程\(ax+by=c\)的一组解就是\((x_oc/g,y_0c/g)\)对吧?如果\(g \nmid c\)无解。
这里补充一个知识点(来自紫书)
设\(a,b,c \in Z\)。若方程\(ax+by=c\)的一组整数解为\((x_0,y_0)\),那么它的任意整数解都可以写成\(x_0+kb',y_0+ka'\),其中\(a'=a/gcd(a,b),b'=b/gcd(a,b)\)
但是题目中求的是最小的\(x\),我们设其为\(x_{min}\),设我们找到的\(ax+by=c\)的一组特解为\(x\)
那么\(x_{min}=x+k*b/gcd(a,b)\),即\(x_{min} \equiv x(mod\;b/gcd(a,b))\)
\[\therefore x_{min}=x\;mod\;b/gcd(a,b)\]
代码:
#include <cstdio>
using namespace std;
typedef long long ll;
inline ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x = 1,y = 0;
return a;
}
ll res = exgcd(b,a % b,y,x);
y -= (a / b) * x;
return res;
}
ll a,b,m,n,l,x,k;
int main(){
scanf("%lld %lld %lld %lld %lld",&a,&b,&m,&n,&l);
ll res = exgcd(m - n,-l,x,k);
if((b - a) % res)return printf("Impossible\n"),0;//判断无解
ll ans = (x * (b - a) / res) % (l / res);//先求出ax+by=c特解x,再求xmin
while(ans < 0)ans += l / res;//处理负数
return printf("%lld\n",ans),0;
}
原文地址:https://www.cnblogs.com/colazcy/p/11515127.html
时间: 2024-10-20 13:37:58