タイトル説明
最小の正の整数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)
この再帰的な実装と実現GCDを比較し、より拡張ユークリッドアルゴリズムである本質その次のx、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;
}
このような考え方は次のようになります。
'= 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