求关于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; }