zoukankan      html  css  js  c++  java
  • luoguP1516 青蛙的约会|数论|同余|扩展欧几里得算法

    青蛙的约会|数论|同余|扩展欧几里得算法

    为什么这种乐(S)观(B)的青蛙都能网恋,还成功了(我:???????SB青蛙去死8 青蛙

    为什么最近一直在做青蛙的题?(我怕是要无限-1s制了????)

    V3

    Problem

    Problem

    分析

    先搞懂扩展欧几里得算法8

    根据题意可得:

    青蛙A:

    初始位置x,每次跳m

    青蛙B:

    初始位置y,每次跳n

    总长度为L

    求相遇时间(如果有解)t

    即换成数学表达式:

    [x+mcdot t equiv y+ncdot t left(mod L ight) ]

    根据分析扩展欧几里得算法的步骤:

    [L|left(x+mcdot t ight)-left(y+ncdot t ight) ]

    =>

    [L|left(x-y ight)+left(m-n ight)t ]

    =>

    [left(x-y ight)+left(m-n ight)t=kL,kin Z^{*} ]

    [n-m=a,x-y=b(a>0,b>0) ]

    注意:

    如果a<0:

    需要把a和b调正:

    [a=-a,b=-b ]

    [acdot t+kcdot L=b ]

    方程有解:

    当且仅当

    [gcdleft(a,k ight)|b ]

    如果有解:

    [acdot t+Lcdot k=gcdleft(a,k ight) ]

    根据扩展欧拉定理得一个解t0

    之后对t0进行操作得到t的一个解:

    [t=t_0cdot frac{b}{gcdleft(a,k ight)} ]

    再进行调正:

    [t=left(t\%frac{L}{d}+frac{L}{d} ight)\%frac{L}{d} ]

    Code

    #include <cstdio>
    #include <iostream>
    #define ll long long 
    using namespace std;
    ll x,y,m,n,l,t,k;
    ll exgcd(ll a,ll b,ll &x,ll &y){
    	if(b==0){
    		x=1,y=0;
    		return a;
    	}
    	int d=exgcd(b,a%b,x,y);
    	int tmp=x;x=y;y=tmp-(a/b)*y;
    	return d;
    }
    int main(){
    	scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);
    	ll a=n-m,b=x-y;
    	if(a<0) a=-a,b=-b;//修正为正数 
    	ll d=exgcd(a,l,t,k);
    	if(b%d==0){
    		t=t*b/d;//获得一个解
    		t=(t%(l/d)+(l/d))%(l/d);//修正负数 
    		printf("%lld",t);
    	}else printf("Impossible");
    	return 0;
    }
    
  • 相关阅读:
    mybatis 入门基础
    spring学习总结
    综合练习:词频统计
    组合数据类型综合练习
    Python基础综合练习
    熟悉常用的Linux操作
    1.大数据概述
    C程序语法(无左递归)
    文法规则
    实验一词法分析报告
  • 原文地址:https://www.cnblogs.com/saitoasuka/p/10338760.html
Copyright © 2011-2022 走看看