【Luogu】P1516青蛙的约会(线性同余方程,扩展欧几里得)

题目链接

定理:对于方程\(ax+by=c\),等价于\(a*x=c(mod b)\),有整数解的充分必要条件是c是gcd(a,b)的整数倍。

      ——信息学奥赛之数学一本通

避免侵权。哈哈。

两只青蛙跳到一格才行,所以说

\(x+mt=y+nt(mod l) \)

\((x-y)+(m-n)t=0(mod l)\)

\((m-n)t+ls=(y-x)  s属于整数集\)

 令a=n-m,b=l,c=gcd(a,b),d=x-y

则有\( at+bs=d\)

扩展欧几里得求解。

设c=gcd(a,b),若d/c 不是整数则无解。

最小解=(c*(d/c)%b+b)%b

这里是扩展欧几里得的代码。

long long exgcd(long long a,long long b,long long &x,long long &y){
    if(b==0){
        y=0;x=1;
        return a;
    }
    long long ret=exgcd(b,a%b,x,y);
    long long tmp=x;x=y;y=tmp-a/b*y;
    return ret;
}
扩展欧几里得

附上解题代码

#include<iostream>
#include<cstdio>
using namespace std;

long long p,q;

long long exgcd(long long a,long long b,long long &x,long long &y){
    if(b==0){
        y=0;x=1;
        return a;
    }
    long long ret=exgcd(b,a%b,x,y);
    long long tmp=x;x=y;y=tmp-a/b*y;
    return ret;
}

int main(){
    long long n,m,x,y,l;
    cin>>x>>y>>m>>n>>l;
    long long a=x-y,b=n-m;
    if(b<0){
        b=-b;a=-a;
    }
    long long c;
    if((a)%(c=exgcd(b,l,p,q))){
        printf("Impossible");
        return 0;
    }
    printf("%lld",((a)/c*p%(l/c)+(l/c))%(l/c));
    return 0;
}

 

posted @ 2017-09-05 20:56  Konoset  阅读(240)  评论(0编辑  收藏  举报