洛谷 p1516 青蛙的約會 題解

dalao們真是太強了,吊打我無名蒟蒻c++

我連題解都看不懂,在此篇題解中,我儘可能用語言描述,不用公式推導(dalao喜歡看公式的話繞道,這篇題解留給像我同樣弱的)spa

進入正題code

若是不會擴展歐裏幾德的話請先去作get

洛谷 p1082 同餘方程it

設跳了k次class

因此km - kn + x - y = 0(mod l)
因此k(m - n) + h * l = y - x
這個移項應該沒問題吧擴展

設(m - n)爲a,k爲x,h爲y,
l爲b,(y - x)爲mgc

那麼轉換爲ax + by = m
根據裴蜀定理ax + by = gcd(a,b)有解語言

但不表明ax + by = m無解
咱們能夠讓等式兩邊同除一個m,再同乘一個gcd(a,b)while

就成了ax / m * gcd(a,b) + by / m * gcd(a,b) = gcd(a,b)

把(x / m * gcd(a,b))做爲新的x,(y / m * gcd(a,b))做爲新的y

再利用擴展歐裏幾德能夠求出新的x
即(x / m * gcd(a,b))

咱們若是求出了(x / m * gcd(a,b)),那麼也能夠求出x(乘一個m再除一個gcd就行了)

可是這並不意味這每一個方程都有解,由於咱們的x表明的是k
也就是x表明跳的次數,因此僅能夠做爲整數
也就是若是咱們必須讓 m整除gcd(a,b)即m % gcd(a,b) == 0
若是m % gcd(a,b)不等於0,那麼方程無解

#include<bits/stdc++.h>

using namespace std;

inline long long read(){long long s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}

long long xx,yy,t,AC = 0;

long long gcd(long long x,long long y){//求gcd
    if(y == 0) return x;
    return gcd(y,x % y);
}

void exgcd(long long a,long long b){//正宗exgcd
    if(b == 0){
        xx = 1;
        yy = 0;
        return ;
    }
    exgcd(b,a % b);
    t = xx;
    xx = yy;
    yy = t - a / b * yy;
}

int main()
{
    long long x = read(),y = read();
    long long m = read(),n = read();
    long long l = read();

    long long a = n - m,b = l,mm = x - y;
    if(a < 0){//咱們讓第一隻青蛙開始再第二隻後面,若是不是這樣就調換位置(~~由於青蛙是同樣的~~)
        mm = -mm;
        a = -a;
    }
    long long g = gcd(a,b);
    long long t = b / g;

    if(mm % g){//不是0則無解
        cout<<"Impossible"<<endl;
        return AC;
    }

    exgcd(a,b);
    long long ans = xx * (mm / g);//我覺得答案就是這樣

    cout<<(ans % t + t) % t<<endl;//至於%t+t%t也是看了其餘大佬的題解才知道的,不過我並不知道爲何,(太弱了,霧)

    return AC;//返回AC保平安
}
相關文章
相關標籤/搜索