求关于x的同余方程 ax ≡ 1(mod b) 的最小正整数解。

输入格式
输入只有一行,包含两个正整数a,b,用一个空格隔开。

输出格式
输出只有一行,包含一个正整数x,表示最小正整数解。

输入数据保证一定有解。

数据范围
2≤a,b≤2∗109
输入样例:
3 10
输出样例:
7

 

 

题意:要求满足题给的式子的最小正整数x

思路:线性同余方程的经典问题

ax ≡ m(mod b)  (原型)  

ax ≡ 1(mod b)   ->    ax - by = 1(因为%b就相当于ax减掉若干个b)

说明只有gcd(a,b)=1时才有解

这里我们就可以化成扩展欧几里得来求解

 

扩欧:   ax+by=gcd(a,b)  ,肯定有x,y能满足这个条件

证明:

1.gcd(a,b)=gcd(b,a%b)

2. 欧几里得算法算到最后,当b=0时,a*1+0*0=gcd(a,0)

3. bx+a%by = gcd(b,a%b)   ->    bx +  (a-a/b*b)y  = gcd(b,a%b)   ->   ay +  b(x-a/b*by) = gcd(b,a%b)  ->  ax' + by' = gcd(a,b)

所以由2我们可知最简形式有x,y满足定理,由1可以推出3,由3可知可以由任何一步推出另一步,所以我们可以用最简形式推出所有的

所以证明扩欧定理的正确性

 

线性同余方程可以化简出扩欧的式子,然后求出x

然后通解为  x+num*b

这里要求为正整数,所以我们要+b%b

#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll x,y;
ll exgcd(ll a,ll b){
    if(b==0){
        x=1;
        y=0;
        return a;
    }
    ll z=exgcd(b,a%b);
    ll t=x;
    x=y;
    y=t-a/b*y;
    return z;
}
int main(){
    ll a,b;
    cin>>a>>b;
    ll z=exgcd(a,b);
    //cout<<z<<endl;
    cout<<(x%b+b)%b<<endl; 
}