51nod 1256 乘法逆元(费马小定理+快速幂+欧拉函数)

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
收藏
关注
取消关注
给出2个数M和N(M < N),且M与N互质,找出一个数K满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。
 
Input
输入2个数M, N中间用空格分隔(1 <= M < N <= 10^9)
Output
输出一个数K,满足0 < K < N且K * M % N = 1,如果有多个满足条件的,输出最小的。
Input示例
2 3
Output示例
2

分析:费马小定理表明一个数a的乘法逆元(关于m取模)等于a^(phi(m)-1).
phi(m)为m的欧拉函数值,显然当m为素数时phi(m)=m-1,即此时的乘法逆元为a^(m-2).

乘法逆元:一个数乘以它的乘法逆元等于1,所以要求a/b可转化成求a*(b的乘法逆元).

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 typedef long long ll;
 5 ll n;//
 6 ll m;
 7 ll pow_mod(ll x,ll i)
 8 {
 9     ll ans=1;
10     while(i)
11     {
12         if(i&1)
13             ans=(ans*x)%n;
14         i>>=1;
15         x=(x*x)%n;
16     }
17     return ans;
18 }
19 ll eular(ll a)
20 {
21     ll ans=a;
22     ll tmp=sqrt(a+0.5);
23     for(ll i=2;i<=tmp;i++)
24     {
25         if(a==1)
26             break;
27         if(a%i==0)
28         {
29             ans=ans/i*(i-1);
30             while(a%i==0)
31                 a/=i;
32         }
33     }
34     if(a!=1)
35         ans=ans/a*(a-1);
36     return ans;
37 }
38 int main()
39 {
40     ios::sync_with_stdio(false);
41     while(cin>>m>>n)
42     {
43         cout<<pow_mod(m,eular(n)-1)%n<<endl;
44     }
45     return 0;
46 }

 

 
posted @ 2017-08-07 16:47  只有你  阅读(371)  评论(0编辑  收藏  举报