The modular modular multiplicative inverse of an integer a modulo m is an integer x such that a-1≡x (mod m)
. This is equivalent to ax≡1 (mod m)
.
Input
There are multiple test cases. The first line of input is an integer T ≈ 2000 indicating the number of test cases.
Each test case contains two integers 0 < a ≤ 1000 and 0 < m ≤ 1000.
Output
For each test case, output the smallest positive x. If such x doesn't exist, output "Not Exist".
Sample Input
3 3 11 4 12 5 13
Sample Output
4 Not Exist 8
解题思路:
这里,我们称 x 是 a 关于 m 的乘法逆元
这怎么求?可以等价于这样的表达式: a*x + m*y = 1
看出什么来了吗?没错,当gcd(a , m) != 1 的时候是没有解的这也是 a*x + b*y = c 有解的充要条件: c % gcd(a , b) == 0
接着乘法逆元讲,一般,我们能够找到无数组解满足条件,但是一般是让你求解出最小的那组解,怎么做?我们求解出来了一个特殊的解 x0 那么,我们用 x0 % m其实就得到了最小的解了。为什么?
可以这样思考:
x 的通解不是 x0 + m*t 吗?
那么,也就是说, a 关于 m 的逆元是一个关于 m 同余的,那么根据最小整数原理,一定存在一个最小的正整数,它是 a 关于m 的逆元,而最小的肯定是在(0 , m)之间的,而且只有一个,这就好解释了。
可能有人注意到了,这里,我写通解的时候并不是 x0 + (m/gcd)*t ,但是想想一下就明白了,gcd = 1,所以写了跟没写是一样的,但是,由于问题的特殊性,有时候我们得到的特解 x0 是一个负数,还有的时候我们的 m 也是一个负数这怎么办?
当 m 是负数的时候,我们取 m 的绝对值就行了,当 x0 是负数的时候,他模上 m 的结果仍然是负数(在计算机计算的结果上是这样的,虽然定义的时候不是这样的),这时候,我们仍然让 x0 对abs(m) 取模,然后结果再加上abs(m) 就行了
/*************************************************************************
> File Name: zoj4712.cpp
> Author: baozi
> Last modified: 2018年08月14日 星期二 14时44分
> status:AC
************************************************************************/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
ll n,m,k,t;
ll ex_gcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
ll gc=ex_gcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return gc;
}
ll cal(ll a,ll m,ll c){
ll x,y;
ll gc=ex_gcd(a,m,x,y);
if(c%gc!=0) return -1;
x*=c/gc;
if(m<0) m=-m;
ll ans=x%m;
if(ans<=0) ans+=m;
return ans;
}
int main(){
int i,j;
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&n,&m);
ll ans=cal(n,m,1);
if(ans==-1) printf("Not Exist\n");
else printf("%d\n",ans);
}
return 0;
}