51nod:1256 乘法逆元(數學)

基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題

給出2個數M和N(M < N),且M與N互質,找出一個數K滿足0 < K < N且K * M % N = 1,如果有多個滿足條件的,輸出最小的。
Input
輸入2個數M, N中間用空格分隔(1 <= M < N <= 10^9)
Output
輸出一個數K,滿足0 < K < N且K * M % N = 1,如果有多個滿足條件的,輸出最小的。
Input示例
2 3
Output示例
2

解題思路:K*M%N=1等價於K*M=1+N*X等價於K*M-X*N=1,這種形式就是不定方程x*m+y*n=gcd(m,n)的形式,這裏m和n給出來了,且互質
,所以gcd(m,n)=1,然後用exgcd求解不定方程即可。

怎麼求呢?我也是第一次學習,感覺這個博主寫的不錯,傳送

我再拷貝下在這裏,以便記住推導過程:

//小小地講一下exgcd球不定方程原理 
 對於ax+by=gcd(a,b);  
我們設一下a>b,在簡單直接把b=0時,gcd(a,b)=a.此時,x=1,y=0;  
接着,a>b>0,我們這裏可以擺兩個式子:①:ax1+by1=gcd(a,b);繼續,②:bx2+(a mod b)y2=gcd( b , a mod b );第二個式子爲何呢?這就是gcd的輾轉相除法的算法啊。而且
gcd(a,b)=gcd(b,a mod b);  
然後我們就能將gcd左邊兩個等式列個等式:ax1+by1=bx2+(a mod b)y2;額。。。a mod b可以寫成?a-(a/b)b對吧,
那麼等式變成ax1+ by1= bx2+ (a - (a / b) * b)y2=bx2+ay2 - (a / b)by2 ;我們把ax1+ by1=bx2+ay2 - (a / b)by2拎出來,整理一下,寫成:ax1+by1=ay2+b(x2-(a/b)y2); 那麼很明顯我
們可以得到,x1=y2,y1=x2-(a/b)y2;  
這樣我們就得到了求解 x1,y1 的方法:x1,y1 的值基於 x2,y2. 


代碼如下:
#include <cstdio>
typedef long long LL;
LL m,n,k,x;
void exgcd(LL a,LL b)
{
	if(b==0)//遞歸結束的終止條件 
    {
        k=1;
        x=0;
        return;
    }
    exgcd(b,a%b);
    LL temp=k;
    k=x;//相當於x1=y2 
    x=temp-(a/b)*x;//相當於y1=x2-(a/b)*y2 
}
int main()
{
	scanf("%lld%lld",&m,&n);
	exgcd(m,n);
	while(k<0)//所求出來的解可能是負的,題目說要最小的正數解,這樣循環把他弄成正數 
	{
		k=(k+n)%n;
	}
	printf("%lld\n",k);
	return 0;
} 

發佈了277 篇原創文章 · 獲贊 20 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章