适合单个的,费马小定理,exgcd,都是不错的选择,利用积性函数的方法和欧拉筛的方法适合批量求,但是论时间和空间的话,还是积性函数的方法比较好用,线性的。

题目链接: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+;
  11. ll quickpow(ll t1,ll t2,ll t){
  12. ll ans=t1%t;
  13. t2--;
  14. while(t2){
  15. if(t2&)ans=ans*t1%t;
  16. t1=t1*t1%t;
  17. t2>>=;
  18. }
  19. return ans%t;
  20. }
  21. ll inv(ll t,ll mod){
  22. return quickpow(t,mod-,mod)%mod;
  23. }
  24. int main(){
  25. ll n,p;
  26. scanf("%lld %lld",&n,&p);
  27. for(int i=;i<=n;i++){
  28. printf("%lld\n",inv(i,p));
  29. }
  30. return ;
  31. }

方法二(超时)(适合求单个):扩展欧几里得

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+;
  11. ll x,y;
  12. void exgcd(ll t1,ll t2,ll mod)
  13. {
  14. if(t2==)
  15. {
  16. x=;
  17. y=;
  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=; i<=n; i++)
  35. {
  36. printf("%lld\n",inv(i,p));
  37. }
  38. return ;
  39. }

方法三(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+;
  11. ll inv[maxn];
  12. int main()
  13. {
  14. ll n,p;
  15. scanf("%lld %lld",&n,&p);
  16. inv[]=;
  17. for(int i=;i<=n;i++){
  18. inv[i]=((p-p/i)*inv[p%i]+p)%p;
  19. }
  20. for(int i=;i<=n;i++){
  21. printf("%lld\n",inv[i]);
  22. }
  23. return ;
  24. }

 方法四:

欧拉筛(可批量求)

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+;
  11. ll inv[maxn],prim[maxn],vis[maxn];
  12. ll quickpow(ll t1,ll t2,ll mod)
  13. {
  14. if(!t2)return ;
  15. ll now=quickpow(t1,t2>>,mod);
  16. now=now*now%mod;
  17. if(t2&)now=now*t1%mod;
  18. return now%mod;
  19. }
  20. int main()
  21. {
  22. ll n,p;
  23. scanf("%lld %lld",&n,&p);
  24. vis[]=;
  25. inv[]=;
  26. int num=;
  27. for(ll i=; i<=n; i++)
  28. {
  29. if(vis[i]==)
  30. {
  31. prim[++num]=i;
  32. inv[i]=quickpow(i,p-,p);
  33. }
  34. for(ll j=; j<=num; j++)
  35. {
  36. if(i*prim[j]>n)
  37. break;
  38. ll tmp=i*prim[j];
  39. vis[tmp]=;
  40. inv[i*prim[j]%p]=inv[i]*inv[prim[j]]%p;
  41. if(i%prim[j]==)
  42. break;
  43. }
  44. }
  45. for(int i=; i<=n; i++)
  46. {
  47. printf("%lld\n",inv[i]);
  48. }
  49. return ;
  50. }

乘法逆元(P3811)(四种方法)的更多相关文章

  1. 两个变量交换的四种方法(Java)

    对于两种变量的交换,我发现四种方法,下面我用Java来演示一下. 1.利用第三个变量交换数值,简单的方法. (代码演示一下) class TestEV //创建一个类 { public static ...

  2. 织梦DedeCMS模板防盗的四种方法

    织梦(DedeCMS)模板也是一种财富,不想自己辛辛苦苦做的模板被盗用,在互联网上出现一些和自己一模一样的网站,就需要做好模板防盗.本文是No牛收集整理自网络,不过网上的版本都没有提供 Nginx 3 ...

  3. 让一个图片在div中居中(四种方法)

    第一种方法: <div class="title"> <div class="flag"></div> <div cl ...

  4. 运行jar应用程序引用其他jar包的四种方法

    转载地址:http://www.iteye.com/topic/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个ja ...

  5. java中定时器的四种方法

    package com.lid; import java.util.Calendar; import java.util.Date; import java.util.Timer; import ja ...

  6. Angular--页面间切换及传值的四种方法

    1. 基于ui-router的页面跳转传参(1) 在AngularJS的app.js中用ui-router定义路由,比如现在有两个页面,一个页面(producers.html)放置了多个produce ...

  7. MYSQL获取自增ID的四种方法

    MYSQL获取自增ID的四种方法 1. select max(id) from tablename 2.SELECT LAST_INSERT_ID() 函数 LAST_INSERT_ID 是与tabl ...

  8. linux下配置ip地址四种方法(图文方法)

    主要是用第四种方法 (1)Ifconfig命令  第一种使用ifconfig命令配置网卡的ip地址.此命令通常用来零时的测试用,计算机启动后 ip地址的配置将自动失效.具体用法如下.Ipconfig  ...

  9. C#播放声音的四种方法 +AxWindowsMediaPlayer的详细用法

    C#播放声音的四种方法 第一种是利用DirectX 1.安装了DirectX SDK(有9个DLL文件).这里我们只用到MicroSoft.DirectX.dll和 Microsoft.Directx ...

  10. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

随机推荐

  1. 软工实践练习一 git使用心得

    使用git进行代码管理的心得 小组 1.结对的同学创建了小组,我属于被邀请的.附上图片一张. 2.已将代码库https://github.com/sefzu2015/AutoCS fork到了小组or ...

  2. Beta阶段冲刺-1

    1. 新成员 新加入成员,克克飞同学,任务是去弄公众号相关的部分. 队员 个人简介 博客地址 杨晨露 每天都在开会的PM http://www.cnblogs.com/ycll/ 游舒婷 每天都在装死 ...

  3. 一篇关于spring ioc 依赖注入3种方式的文章引用

    今天看到一篇spring ioc 容器依赖注入3种方式的文章,为了方便后面的复习,在此引用别人的文章,查看请戳我.

  4. squid介绍和作用

    介绍 squid服务程序是一款在Unix系统中最为流行的高性能代理服务软件,通常会被当作网站的前置缓存服务,用于替代用户向网站服务器请求页面数据并进行缓存,通俗来讲,Squid服务程序会接收用户的请求 ...

  5. PAT 甲级 1086 Tree Traversals Again

    https://pintia.cn/problem-sets/994805342720868352/problems/994805380754817024 An inorder binary tree ...

  6. Parameter not found的出现的原因

      with dataM.Q_xfgl_dhjf do   begin     close;     sql.Clear;     sql.Add('insert into jfdh(jfdh_id, ...

  7. git learn

    $ git config --global user.name "Your Name" $ git config --global user.email "email@e ...

  8. 群里提到的IE设置问题 ---B/S 下页面刷新问题

    这里面四个选项的含义 下面是每个选项的作用和意义: 1. “每次访问此页时检查”选项表示浏览器每次访问一个页面时,不管浏览器是否缓存过此页面,都要向服务器发出访问请求.这种设置的优点是实时性很强,肯定 ...

  9. google学术登陆不上的解决办法

    打开我的电脑,依次打开C盘,Windows,System32,drivers,etc 即C:\Windows\System32\drivers\etc   用记事本打开etc文件夹中的hosts. 在 ...

  10. robotframework 赋予临时id

    有的时候用rf执行ui自动化测试脚本的时候,一直提示找不到元素 (前提是没有id) 那么这个时候 我们可以随便赋予一个临时id Assign Id To Element      xpath=//*[ ...