题解 P1516 【青蛙的约会】

题目链接

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;
}
上一篇:大数据之-Hadoop3.x_MapReduce_Combiner概述---大数据之hadoop3.x工作笔记0118


下一篇:Java动态菜单添加