TZOJ4295--Modular Inverse
题目简述:
给你一个整数a(0<a<=1000)和一个模数m(0<m<=1000),问是否存在一个正整数x使得a*x%m=1,使x尽可能小。
标准输入
3
3 11
4 12
5 13
标准输出
4
Not Exist
8
思路1:
暴力,观察数据很显然,x的范围是0~(m-1),由于输出要求x为正整数,当x=0时应输出m。枚举1~m即可,能使得a*x%m=1,那么此时x就是答案,否则输出“Not Exist”。
思路2:
通过逆元来求。由于m保证是质数,所以快速幂求逆元不能用,得用扩展欧几里得求逆元。此时式子转变成 ax+my=gcd(a,m),如果gcd(a,m)不等于1,则不存在逆元。若存在,则x变量就是所求逆元。为了保证x是最小正整数,做这最后一步操作即可(x%mod+mod)%mod。
暴力代码就不展示了。
展示扩欧的代码。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); 4 #define int long long 5 typedef unsigned long long llu; 6 const double e=1e-7; 7 const int N=1e5+7; 8 const int MOD=1e9+7; 9 const int LINF=1e18; 10 const int P=131; 11 bool C=1; 12 13 int exgcd(int a,int b,int &x,int &y){ 14 if(b==0){ 15 x=1,y=0;return a; 16 } 17 int X1,Y1,d; 18 d=exgcd(b,a%b,X1,Y1); 19 x=Y1,y=X1-a/b*Y1; 20 return d; 21 } 22 void solve(){ 23 int n,m; 24 cin>>n>>m; 25 if(__gcd(n,m)!=1){ 26 cout<<"Not Exist"<<endl; 27 return; 28 } 29 int x,y; 30 exgcd(n,m,x,y); 31 x=(x%m+m)%m; 32 if(x==0) x=m; 33 cout<<x<<endl; 34 } 35 signed main(){ 36 IOS; 37 int t; 38 if(C) cin>>t; 39 else t=1; 40 while(t--) solve(); 41 }