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; }
skr