乘法逆元(P3811)

Posted letlifestop

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乘法逆元(P3811)相关的知识,希望对你有一定的参考价值。

题目链接:https://www.luogu.org/problemnew/show/P3811

方法一(超时):费马小定理
当p为素数的时候,a^(p-1)=1(在模p的情况下),所以我们就可以推导出,a*a^(p-2)=1,所以a的逆元就是a^(p-2)。

代码:

技术分享图片
 1 #include<iostream>
 2 #include<stack>
 3 #include<cmath>
 4 #include<queue>
 5 #include<stdio.h>
 6 #include<algorithm>
 7 using namespace std;
 8 # define ll long long
 9 # define inf 0x3f3f3f3f
10 const int maxn = 1e5+100;
11 ll quickpow(ll t1,ll t2,ll t){
12 ll ans=t1%t;
13 t2--;
14 while(t2){
15 if(t2&1)ans=ans*t1%t;
16 t1=t1*t1%t;
17 t2>>=1;
18 }
19 return ans%t;
20 }
21 ll inv(ll t,ll mod){
22 return quickpow(t,mod-2,mod)%mod;
23 }
24 int main(){
25 ll n,p;
26 scanf("%lld %lld",&n,&p);
27 for(int i=1;i<=n;i++){
28 printf("%lld
",inv(i,p));
29 }
30 return 0;
31 }
View Code

方法二(超时):扩展欧几里得

a*x=1(mod p),我们可以列出等式,a*x+p*y=1,利用扩展欧几里得,直接求出x。

代码:

技术分享图片
 1 #include<iostream>
 2 #include<stack>
 3 #include<cmath>
 4 #include<queue>
 5 #include<stdio.h>
 6 #include<algorithm>
 7 using namespace std;
 8 # define ll long long
 9 # define inf 0x3f3f3f3f
10 const int maxn = 1e5+100;
11 ll x,y;
12 void exgcd(ll t1,ll t2,ll mod)
13 {
14     if(t2==0)
15     {
16         x=1;
17         y=0;
18         return ;
19     }
20     exgcd(t2,t1%t2,mod);
21     ll tmp=x%mod;
22     x=y%mod;
23     y=(tmp-t1/t2*y%mod+mod)%mod;
24 }
25 ll inv(ll t,ll mod)
26 {
27     exgcd(t,mod,mod);
28     return x%mod;
29 }
30 int main()
31 {
32     ll n,p;
33     scanf("%lld %lld",&n,&p);
34     for(int i=1; i<=n; i++)
35     {
36         printf("%lld
",inv(i,p));
37     }
38     return 0;
39 }
View Code

方法三(AC):欧拉函数

证明方法如下图所示:

技术分享图片

AC代码:

技术分享图片
 1 #include<iostream>
 2 #include<stack>
 3 #include<cmath>
 4 #include<queue>
 5 #include<stdio.h>
 6 #include<algorithm>
 7 using namespace std;
 8 # define ll long long
 9 # define inf 0x3f3f3f3f
10 const int maxn = 2e7+1000;
11 ll inv[maxn];
12 int main()
13 {
14     ll n,p;
15     scanf("%lld %lld",&n,&p);
16     inv[1]=1;
17     for(int i=2;i<=n;i++){
18     inv[i]=((p-p/i)*inv[p%i]+p)%p;
19     }
20     for(int i=1;i<=n;i++){
21     printf("%lld
",inv[i]);
22     }
23     return 0;
24 }
View Code

 


以上是关于乘法逆元(P3811)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P3811 模板乘法逆元 如题

[洛谷P3811]模板乘法逆元

P3811 模板乘法逆元

题解 P3811 模板乘法逆元

P3811 模板乘法逆元

luogu P3811 模板乘法逆元