zoukankan      html  css  js  c++  java
  • bzoj1477: 青蛙的约会

    传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1477

    思路:扩展欧几里德求解同余方程。

    设x步后碰面,初始位置为x0,y0。

    那么就有x0+mx=y0+nx(mod L)

    (m-n)x=y0-x0(mod L) //程序里要先把m-n变成正数,L已经是正数,不用变,负数模会有问题,这两步的等号是同余。

    于是就可以把这个同余方程变为不定方程ax+by=c

     (m-n+L*t)x+Ly=(y0-x0) modL

    然后就是exgcd的事了。


    exgcd是用来求ax+by=Gcd(a,b)的整数解的

    借用gcd的思想

    bx'+(a%b)y'=gcd(b,a%b)

    只要把这个方程化为上一个方程的形式,那么我们就可以由下一层推出这一层的解。

    于是有bx'+(a-(a/b)*b)y'=gcd(b,a%b)

    ay'+b(x'-(a/b)y')=gcd(b,a%b)

    gcd(b,a%b)=gcd(a,b)

    所以x=y',y=(x'-(a/b)y')

    递归的底层即当b=0时,显然,x=1,y=0是一组解。

    于是我们就可以层层向上求出一组解


    对于ax+by=c的求解可以先求出ax+by=gcd(a,b),然后将x,y扩大c/gcd(a,b)倍就可以了。

    无解(整数解)就是c%gcd(a,b)!=0,

    当Gcd(a,b)=1时//没有这个就会漏解

    通解即为 x=x0+bt

        y=y0-at

    于是就可以求最小整数解之类的问题了


    对于这道题,只要求出 (m-n+L*t)x+Ly=(y0-x0) mod L的最小整数解即可

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    ll x0,y0,m,n,L;
    
    ll exgcd(ll a,ll b,ll &x,ll &y){
    	if (b==0){x=1,y=0;return a;}
    	int Z=exgcd(b,a%b,x,y),t=x;
    	x=y,y=t-a/b*y;return Z;
    }
    int gcd(int a,int b){return !b?a:gcd(b,a%b);}
    
    int main(){
    	scanf("%lld%lld%lld%lld%lld",&x0,&y0,&m,&n,&L);
    	ll A=((m-n)%L+L)%L,B=L,C=y0-x0,x,y,t=exgcd(A,B,x,y);
    	if (C%t!=0){puts("Impossible");return 0;}
    	A/=t,B/=t,C/=t,x=(x*C%B+B)%B;
    	printf("%lld
    ",x);
    	return 0;
    }



  • 相关阅读:
    kettle plugin 插件开发
    eclipse插件hibernate tools安装
    全面总结Java泛型 使用案例
    向刚工作的人解释什么叫工作!
    Hibernate 的HQL,QBC 查询语言
    JQuery Highcharts图表控件使用说明
    JSP 的脚本,指令,动作
    ODI OWB 特性比较说明
    Win32 框架文档视图(3)
    Win32 框架文档视图(2)
  • 原文地址:https://www.cnblogs.com/thythy/p/5493526.html
Copyright © 2011-2022 走看看