ZOJ 4712 Modular Inverse (乘法逆元)

版权声明:转载请说明出处 https://blog.csdn.net/bao___zi/article/details/81667656

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;
}

猜你喜欢

转载自blog.csdn.net/bao___zi/article/details/81667656