合同方程式の求解レポートおよび拡張ユークリッドを説明NOIP2012Day2T1

タイトル説明

最小の正の整数AX≡X 1(MOD b)の溶液に対して合同式を求めます。

入力と出力のフォーマット
入力フォーマット:

唯一のライン入力は、2つの正の整数、Bを含む、スペースで区切られました。

出力フォーマット:

正の整数X0を含むだけ出力ライン、すなわち、最小の正の整数解。入力データが解ける保証しました。

サンプル入力と出力

入力サンプル#1:
310

出力サンプル#1:
7

説明

[データ範囲]

データの40%、2≤b≤1,000。

データの60%、2≤b≤5000万ため、

データの100%、2≤a、b≤2,000,000,000します。

次の日の最初の質問をグループを改善するためNOIP 2012

これは私が以下同じax≡kmod(b)は言う最初の前に数論、正式な概念の合同の対象である彼のフォームを変換することができる - このような>斧MOD B = Kフォーム。集合論の言語では、厳密に言えばこれです:

整数Zの集合の任意のサブセットについて、n個のZに属する任意の要素のために、N M、Iは、0,1,2を得ることができる...、M-1、M種類の合計数で分割されます。我々は、サイズ標準として残り、Zmを、M個の互いに素なサブセットZ0、Z1、Z2、... ZM-1に分割されます。

ZIは、任意の2つの要素、Bについて、同じI mの程度です。表記

a≡b(MOD M)。
我々は解決合同式は、拡張ユークリッドで使用することができます
平均おそらく次のようです

int E_gcd(int a,int b,int &x,int &y){
    int ret,temp;
    if(!b){
        x=1;y=0;
        return a;
    }
    ret=E_gcd(b,a%b,x,y);
    temp=x;
    x=y;
    y=temp-a/b*y;
    return ret;
}

ここで私たちは、それ自体が関数定義はxにアドレス分の変化、yの値に、独自の識別子を追加するときに、アルゴリズム自体を実装するように変更され、Y、Xにしたいので。
コード自体を記述するだけでなく、それ自体を拡張した後ので、ユークリッドのアルゴリズムを理解します

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

int a,b,x,y;

inline int gcd(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    int r=gcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return r;
}

int main()
{
    scanf("%d%d",&a,&b);
    gcd(a,b,x,y);
    printf("%d",(x+b)%b);
turn 
0;
}

私たちの下に、拡張ユークリッド

アウトライン

二つの整数、B最大公約数を計算するユークリッドアルゴリズムとして知られているユークリッドアルゴリズム。原則の計算は次の定理に依存しています:

機能の最大公約数GCD(A、B)を見つけるために使用されます。

GCD関数の基本的なプロパティ:

GCD(a、b)は= GCD(B)= GCD(-a、B)= GCD(| |、| B |)

数式表現

GCD(A、B)= GCD(B、MOD B)

それを実証する:= KB + rと表すことができ、次いで、R = MOD B

仮定dがあり、Bの公約数であり、

D |、D | B、およびR = - キロバイト、そうD | R

Dは、このように除数の(B、MOD b)は

Dは、除数の(B、MOD B)ことを想定しています

D | B、D | Rが、A = KB + R

Dは、除数の(b)のことです

従って証拠を与えるにバインドされて最大公約数に等しい(B)、及び除数が同じである(B、MOD b)は、
言語

int gcd(int a,int b){
return b?gcd(b,a%b):a;
}

拡張アルゴリズム

不完全非負整数0、bについて、GCD(b)は、を表し最大公約数B必ずしも
X、Yの整数、例えばGCD(A、B)= AXその +によって。
言語

int gcd(int a,int b,int &x,int &y){
if (b==0){
x=1,y=0;
return a;
}
int q=gcd(b,a%b,y,x);
y-=a/b*x;
return q;
}

Xを解決する方法、のYが理解

> Bを提供します。

1、明らかにB = 0、GCD(A、B)=。このとき、X = 1、Y = 0。

2、A> B> 0时

AX1 + BY1 = GCD(A、B)が設けられ、

BX2 +(MOD B)Y2 = GCD(B、MOD B)。

そこGCD(A、B)= GCD(B、MOD b)は、単純なユークリッドの原理に従いました。

その後:AX1 + BY1 = BX2 +(MOD b)のY2;

即:AX1 + BY1 = BX2 +( - [/ B] * b)は、Y2 = AY2 + bx2- [/ B] * BY2。

即ちAX1 + BY1 == AY2 + B(x2- [/ B] * Y2)。

一致の定理:X1 = Y2、Y1 = x2- [/ B] * Y2。

X1、Y1値ベースX2、Y2:我々はX1、Y1の方法を解決するようになったので。

GCD常に再帰溶液が時間B = 0が存在することになるので、再帰を終了することができるので、上記の考え方は、再帰的に定義されています。

拡張ユークリッドの互除法

拡張ユークリッドアルゴリズムが知られて使用される、xのセットを解くB YようによってAX + = GCD(A、B)= D(数字の理論によれば、溶液、定理が存在しなければなりません)。線形方程式および方程式を解くに使用される拡張ユークリッド型。実装:

int exGcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;y=0;
return a;
}
int r=exGcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
return r;
}
この再帰的な実装と実現GCDを比較し、より拡張ユークリッドアルゴリズムである本質その次のx、yの割り当て処理のが見つかりました。

このような考え方は次のようになります。

'= B、B' のため=%Bの、我々は、xを見つけ、Yようa'x + b'y = GCD( 'B')

B「=%のB = AA / B * B(:/プログラミング言語の一部門であることに注意)ので

あなたは得ることができます:

a'x + b'y = GCD( 'B')===>

BX +( - / B * B)Y = GCD( 'B')= GCD(a、b)は===>

AY + B(X - / B * Y)= GCD(a、b)は

こうしてB用、彼らはP、Qに対応し、Yは、(XA / B * Y)であります

不定方程式アプローチを解決するために、拡張ユークリッドアルゴリズムを使用します

C MOD GCD(A、B)= 0、方程式の解の整数、整数または溶液が存在する場合、整数PA + QB = Cについて不定方程式。

ではないことを証明するために、より厳格な方法のようなものが、少しの空白まで少なくともメイク、いくつかの数論の第一人者追加の修正を願っています:

我々が知っているので、xのセットとyが存在するように* X + B * Y = GCD(A、B)。

同時に整数k、即ち、* X * K + B * Y * K = GCD(A、B)* kの両側の式を乗算します。もしC MOD GCD(A、B)= F、次いで、0 <= F

公開された41元の記事 ウォン称賛58 ビュー60000 +

おすすめ

転載: blog.csdn.net/a1351937368/article/details/77660946