LuoGuP1516 青蛙的约会 + 同余方程 拓展欧几里得

题意:有两只青蛙,在一个圆上顺时针跳,问最少的相遇时间。
 
这个是同余方程的思路。可列出方程:(m-n)* X% L = y-x(mod L)
  简化为 a * x = b (mod L) 
   
(1)判断是否有解 ,b % gcd(a,L) == 0 ,有得解。
(2)求通解下的最小正整数解,就是通解对(L / gcd(a, L) ) 取模。
 
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;

#define pb push_back
#define fi first
#define se second
#define debug(x) cerr << #x <<"=" << x<<endl
const int maxn = 1009;
const int inf = 0x3f3f3f3f;

typedef long long ll;
ll x,y,m,n,l;
ll X,Y;
ll gcd(ll a, ll b){
    if(b==0)return a;
    else return gcd(b , a%b);
}

void exgcd( ll a,ll b){
    if(b==0){
        X = 1;
        Y = 0;
        return ;
    }
    exgcd(b, a%b);
    ll tmp = X;
    X = Y;
    Y = tmp - 1ll*(a / b)* Y;
}
int main(){
    cin>>x>>y>>m>>n>>l;
    ll a = 1ll*(m-n), b = 1ll*(y - x);    //a * t + l * y = b (**);
    if(a<0){
        a = -a ;
        b = -b;
    }
    if(b % gcd(a,l)!=0)            //同余方程成立条件。
    {
        puts("Impossible");
        return 0;
    }

    exgcd(a,l);                    //解同余方程a * t + l * y = gcd(a,l)(*);
    // debug(X);
    ll L = l / gcd(a,l);
    X = 1ll*(b / gcd(a,l)) * X;        //同余的结果是(*)的解,转化为(**)的解
    X = (X%L + L) % L;                //对L取余而不是对l取余,是因为定理,可得最小正整数解。
    printf("%lld\n", X );

    return 0;
}
P1516

 

posted @ 2018-07-14 15:36  ckxkexing  阅读(148)  评论(0编辑  收藏  举报