數論-裴蜀定理-Acwing-五指山

數論-裴蜀定理-Acwing-五指山

題目:

大聖在佛祖的手掌中。

我們假設佛祖的手掌是一個圓圈,圓圈的長爲 n,逆時針記爲:0,1,2,…,n−1,而大聖每次飛的距離爲 d。

現在大聖所在的位置記爲 x,而大聖想去的地方在 y。

要你告訴大聖至少要飛多少次才能到達目的地。

注意:孫悟空的筋斗雲只沿着逆時針方向翻。

輸入格式
有多組測試數據。

第一行是一個正整數 T,表示測試數據的組數;

每組測試數據包括一行,四個非負整數,分別爲如來手掌圓圈的長度 n,筋斗所能飛的距離 d,大聖的初始位置 x 和大聖想去的地方 y。

輸出格式
對於每組測試數據,輸出一行,給出大聖最少要翻多少個筋斗雲才能到達目的地。

如果無論翻多少個筋斗雲也不能到達,輸出 Impossible。

數據範圍
2<n<109,
0<d<n,
0≤x,y<n
輸入樣例:
2
3 2 0 2
3 2 0 1
輸出樣例:
1
2

題意:

n0,1,2,...,n1xdy,給定一個圈,有n個點0,1,2,...,n-1。\\從起始位置x開始,每次可以移動d個點,問能否到達位置y,若能,輸出最小次數。

x+bdy(modn),b=0,1,2,...b列出方程:x+bd≡y(modn),其中b=0,1,2,...。即求該方程中b的最小整數解。

x+bd=y+ana=0,1,2,...上述方程可轉化爲:x+bd=y+an,a=0,1,2,...。

n(a)+db=yx(a,b)即:求n(-a)+db=y-x是否有整數解(-a,b)。

裴蜀定理:

a,b,gcd(a,b)=dx,y,ax+bydx,y使ax+by=d若a,b是整數,且gcd(a,b)=d,那麼對於任意的整數x,y,ax+by都一定是d的倍數,\\特別地,一定存在整數x,y,使ax+by=d成立。

重要推論: a,bx,y使ax+by=1a,b互質的充要條件是存在整數x,y使ax+by=1。

a,bax+by那麼若a,b互質,上述推論兩邊擴大任意倍,ax+by可以取到任意整數。

裴蜀定理的通解: ax0+by0=d,ax+by=d{x=x0+kby=y0kak=1,2,...a=ad,b=bd若ax_0+by_0=d,則方程ax+by=d的通解爲:\begin{cases}x=x_0+kb'\\y=y_0-ka' \end{cases},其中k=1,2,...。a'=\frac{a}{d},b'=\frac{b}{d}。

 {ax0+by0=dax+by=d,a(xx0)=b(y0y),a(xx0)=b(y0y)ba(xx0)\ \\ 證明:\begin{cases}ax_0+by_0=d\\ax+by=d\end{cases},兩式相減,得a(x-x_0)=b(y_0-y),則a'(x-x_0)=b'(y_0-y),從而b'|a'(x-x_0)。

gcd(a,b)=1b(xx0)x=x0+kby=y0kak=1,2,...又因爲gcd(a',b')=1,所以b'|(x-x_0),所以x=x_0+kb'。同理,y=y_0-ka' 。k=1,2,...。

所以知道一組特殊解,可以求得任意解。

擴展歐幾里得算法: ——x0,y0遞歸求x_0,y_0

gcd(a,b)=gcd(b,a%b)ax+by=dbx+(a%b)y=d,bx+(a%b)y=bx+(abab)y=ay+b(xaby)=d,{x=yy=xaby由gcd(a,b)=gcd(b,a\%b),對方程ax+by=d也求其下一個狀態,等價於bx+(a\%b)y=d,\\而bx+(a\%b)y=bx+(a-b\lfloor\frac{a}{b}\rfloor)y=ay+b(x-\lfloor\frac{a}{b}\rfloor y)=d,得到解\begin{cases}x'=y\\y'=x-\lfloor\frac{a}{b}\rfloor y\end{cases}
代碼:

int exgcd(int a,int b,int &x,int &y)//擴展歐幾里得算法
{
    if(!b)
    {
        x=1;y=0;
        return a;  //到達遞歸邊界開始向上一層返回
    }
    int d=exgcd(b,a%b,x,y);
    int temp=y;    //把x y變成上一層的
    y=x-(a/b)*y;
    x=temp;
    return d;     //得到a b的最大公因數
}

n(a)+db=yx(a,b)myx滿n(a)+db=mmyxyxgcd(n,d)n(a)+db=yx,b×yxgcd(n,d)回到本題中,要求n(-a)+db=y-x是否有整數解(-a,b),就是要判斷是否存在m|y-x,滿足n(-a)+db=m。\\即m是y-x的因子,可以方程兩邊同時擴大\frac{y-x}{gcd(n,d)}得到n(-a)+db=y-x,得到的解就是b×\frac{y-x}{gcd(n,d)}。

bb0,b=b0+kngcd(n,d)bmin=b0%ngcd(n,d)並且要求最小的次數b,我們知道若求出一組解b_0,則b=b_0+k\frac{n}{gcd(n,d)},則b_{min}=b_0\%\frac{n}{gcd(n,d)}。

代碼:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

ll exgcd(ll a,ll b,ll &x,ll &y)//擴展歐幾里得算法
{
    if(!b)
    {
        x=1;y=0;
        return a;  //到達遞歸邊界開始向上一層返回
    }
    ll d=exgcd(b,a%b,x,y);
    ll temp=y;    //把x y變成上一層的
    y=x-(a/b)*y;
    x=temp;
    return d;     //得到a b的最大公因數
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T -- )
    {
        ll n, d, x, y, a, b;
        scanf("%lld%lld%lld%lld", &n, &d, &x, &y);

        int gcd = exgcd(n, d, a, b);
        if ((y - x) % gcd) puts("Impossible");
        else
        {
            b *= (y - x) / gcd;
            n /= gcd;
            printf("%lld\n", (b % n + n) % n);  ///防止出現負數
        }
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章