洛谷P1516 青蛙的约会(扩展欧几里得EXGCD)
TITLE
思路
a ∗ x + b ∗ y = c 存 在 整 数 解 当 且 仅 当 gcd ( a , b ) ∣ c a*x+b*y=c存在整数解当且仅当\gcd(a,b)|c a∗x+b∗y=c存在整数解当且仅当gcd(a,b)∣c
扩 展 欧 几 里 得 算 法 实 现 求 解 二 元 一 次 不 定 方 程 的 整 数 解 扩展欧几里得算法实现求解二元一次不定方程的整数解 扩展欧几里得算法实现求解二元一次不定方程的整数解
若 求 出 a ∗ x ′ + b ∗ y ′ = gcd ( a , b ) , 那 么 将 等 式 两 边 变 为 原 来 的 c / gcd ( a , b ) 倍 若求出a*x'+b*y'=\gcd(a,b),那么将等式两边变为原来的c/\gcd(a,b)倍 若求出a∗x′+b∗y′=gcd(a,b),那么将等式两边变为原来的c/gcd(a,b)倍
a ∗ x + b ∗ y = gcd ( a , b ) a*x+b*y=\gcd(a,b) a∗x+b∗y=gcd(a,b)
∵ gcd ( a , b ) = gcd ( b , a m o d b ) \because \gcd(a,b)=\gcd(b,a \bmod b) ∵gcd(a,b)=gcd(b,amodb)
∵ a m o d b = a − ⌊ a / b ⌋ ∗ b \because a\bmod b=a-\left\lfloor a/b \right\rfloor*b ∵amodb=a−⌊a/b⌋∗b
设 b ∗ x ′ + a m o d b ∗ y ′ = gcd ( b , a m o d b ) 设b*x'+a\bmod b*y'=\gcd(b,a\bmod b) 设b∗x′+amodb∗y′=gcd(b,amodb)
∴ b ∗ x ′ + ( a − ⌊ a / b ⌋ ∗ b ) ∗ y ′ = gcd ( a , b ) \therefore b*x'+(a-\left\lfloor a/b \right\rfloor*b)*y'=\gcd(a,b) ∴b∗x′+(a−⌊a/b⌋∗b)∗y′=gcd(a,b)
∴ b ∗ x ′ + a ∗ y ′ − ⌊ a / b ⌋ ∗ b ∗ y ′ = a ∗ x + b ∗ y \therefore b*x'+a*y'-\left\lfloor a/b \right\rfloor*b*y'=a*x+b*y ∴b∗x′+a∗y′−⌊a/b⌋∗b∗y′=a∗x+b∗y
令 x = y ′ 令x=y' 令x=y′
∴ b ∗ x ′ + a ∗ x − ⌊ a / b ⌋ ∗ b ∗ x = a ∗ x + b ∗ y \therefore b*x'+a*x-\left\lfloor a/b \right\rfloor*b*x=a*x+b*y ∴b∗x′+a∗x−⌊a/b⌋∗b∗x=a∗x+b∗y
∴ b ∗ x ′ − ⌊ a / b ⌋ ∗ b ∗ x = b ∗ y \therefore b*x'-\left\lfloor a/b \right\rfloor*b*x=b*y ∴b∗x′−⌊a/b⌋∗b∗x=b∗y
∴ x ′ − ⌊ a / b ⌋ ∗ x = y \therefore x'-\left\lfloor a/b \right\rfloor*x=y ∴x′−⌊a/b⌋∗x=y
∴ y = x ′ − ⌊ a / b ⌋ ∗ y ′ \therefore y=x'-\left\lfloor a/b \right\rfloor*y' ∴y=x′−⌊a/b⌋∗y′
x = y ′ , y = x ′ − ⌊ a / b ⌋ ∗ y ′ x=y',y=x'-\left\lfloor a/b\right\rfloor*y' x=y′,y=x′−⌊a/b⌋∗y′
当 b = 0 当b=0 当b=0
a ∗ 1 + 0 ∗ 0 = gcd ( a , 0 ) a*1+0*0=\gcd(a,0) a∗1+0∗0=gcd(a,0)
x = 1 , y = 0 x=1,y=0 x=1,y=0
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(!b){
x=1,y=0;return a;}
long long ans=exgcd(b,a%b,x,y),tem=x;
x=y,y=tem-a/b*y;
return ans;
}
设 x 0 , y 0 是 a x + b y = gcd ( a , b ) 的 一 个 特 解 , 那 么 通 解 为 : 设x0,y0是ax+by=\gcd(a,b)的一个特解,那么通解为: 设x0,y0是ax+by=gcd(a,b)的一个特解,那么通解为:
x = x 0 + b / gcd ( a , b ) ∗ t , x=x0+b/\gcd(a,b)*t, x=x0+b/gcd(a,b)∗t,
y = y 0 − a / gcd ( a , b ) ∗ t , y=y0-a/\gcd(a,b)*t, y=y0−a/gcd(a,b)∗t,
t 为 任 意 整 数 , 可 以 应 用 至 求 最 小 非 负 整 数 解 t为任意整数,可以应用至求最小非负整数解 t为任意整数,可以应用至求最小非负整数解
CODE
#include<iostream>
#include<cstdio>
using namespace std;
long long gcd(long long x,long long y)
{
for(long long r=x%y;r;x=y,y=r,r=x%y);
return y;
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(!b){
x=1,y=0;return a;}
long long ans=exgcd(b,a%b,x,y),tem=x;
x=y,y=tem-a/b*y;
return ans;
}
int main()
{
long long x,y,m,n,l,a,b,g,ans;
scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
if(n>m)b=x-y,a=n-m;
else b=y-x,a=m-n;
ans=exgcd(a,l,x,y);
if(b%ans)printf("Impossible");
else printf("%lld",(b/ans*x%(l/ans)+(l/ans))%(l/ans));
return 0;
}