J - Modular Inverse ZOJ - 3609
Each test case contains two integers 0 < a ≤ 1000 and 0 < m ≤ 1000.
<h4< dd="">For each test case, output the smallest positive x. If such x doesn't exist, output "Not Exist".
<h4< dd="">3 3 11 4 12 5 13<h4< dd="">
4 Not Exist 8
题意分析:
乘法逆元:举个例子:
4关于1模7的乘法逆元为多少?
4X≡1 mod 7
这个方程等价于求一个X和K,满足
4X=7K+1
其中X和K都是整数。
例:求5的模7逆
做辗转相除法, 求得整数b,k使得 5p+7q=1, 则p是5的模7逆,q是7的模5逆。
计算如下:
7=5+2, 5=2×2+1.
回代 1=5-2×2=5-2×(7-5)= 3×5-2×7,
得 5^ -1≡3(mod7).(其中“^”是次方的意思)
例:求21的模73逆
做辗转相除法, 求得整数b,k使得 21p+73q=1, 则p是21的模73逆,q是73的模21逆。
计算如下:
73=21*3+10
21=10*2+1
回代 1=21-10*2
1=21-(73-21*3)*2
=21-73*2+6*21
=7*21-73*2
得 21^ -1≡7(mod73). (其中“^”是次方的意思)
只有两个数互质的时候才存在乘法逆元
AC代码:
#include<iostream> #include<string.h> #include<cstring> #include<string> using namespace std; void gcd(int a,int b,int& d,int& x,int& y) { if(!b) { d=a;x=1;y=0; } else { gcd(b,a%b,d,y,x); y-=x*(a/b); } }//扩展欧几里得算法,a,b,是输入量 //d为gcd(a,b),x,y为ax+by=gcd(a,b)的一组整数解 int main() { int T; cin>>T; while(T--) { int a,m,d,x,y; cin>>a>>m; gcd(a,m,d,x,y); if(d!=1) cout<<"Not Exist\n"; else { //根据一组解求满足条件的x if(x>0) { while(x>0) x-=m; x+=m; } else if(x<0) { while(x<0) x+=m; } else x+=m; cout<<x<<'\n'; } } return 0; }