洛谷P1516 青蛙的约会(扩展欧几里得EXGCD)

洛谷P1516 青蛙的约会(扩展欧几里得EXGCD)

TITLE

思路

a ∗ x + b ∗ y = c 存 在 整 数 解 当 且 仅 当 gcd ⁡ ( a , b ) ∣ c a*x+b*y=c存在整数解当且仅当\gcd(a,b)|c ax+by=cgcd(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)倍 ax+by=gcd(a,b)c/gcd(a,b)

a ∗ x + b ∗ y = gcd ⁡ ( a , b ) a*x+b*y=\gcd(a,b) ax+by=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=aa/bb

设 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) bx+amodby=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) bx+(aa/bb)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 bx+aya/bby=ax+by

令 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 bx+axa/bbx=ax+by

扫描二维码关注公众号,回复: 13266953 查看本文章

∴ b ∗ x ′ − ⌊ a / b ⌋ ∗ b ∗ x = b ∗ y \therefore b*x'-\left\lfloor a/b \right\rfloor*b*x=b*y bxa/bbx=by

∴ x ′ − ⌊ a / b ⌋ ∗ x = y \therefore x'-\left\lfloor a/b \right\rfloor*x=y xa/bx=y

∴ y = x ′ − ⌊ a / b ⌋ ∗ y ′ \therefore y=x'-\left\lfloor a/b \right\rfloor*y' y=xa/by

x = y ′ , y = x ′ − ⌊ a / b ⌋ ∗ y ′ x=y',y=x'-\left\lfloor a/b\right\rfloor*y' x=y,y=xa/by

当 b = 0 当b=0 b=0

a ∗ 1 + 0 ∗ 0 = gcd ⁡ ( a , 0 ) a*1+0*0=\gcd(a,0) a1+00=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,y0ax+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=y0a/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;
}

猜你喜欢

转载自blog.csdn.net/weixin_46975572/article/details/117027279