upd--7.6 原线性求逆元代码有另一种更优写法

  • 题目链接:

    https://www.luogu.org/problemnew/show/P3811

  • 概念:

    一想到JXOI 2018考场上忘记逆元怎么打就觉得好笑,白白让T1落得如此下场.

    推荐阅读:https://www.luogu.org/blog/zjp-shadow/cheng-fa-ni-yuan

    我们可能经常遇到这样的情况(如JXOI2018 T1)

    计算一个类似\(a/b\)%\(p\)的式子,根据同余性质我们是不能$a \(%p\) /b \(%p\) $这样计算的

    但如果在普通算式中,显然\(a/b\)=\(a*b^-1\)。

    在\(\pmod p\)中的意义下,我们不妨也构造一个\(b^-1\),使得\(b*b^{-1} \equiv 1 \pmod{p}\);

    那么\(a/b \pmod p \equiv a*b^{-1} \pmod p\),对于一开始的问题,我们可以放心地将\(a\)%\(p\),然后乘上\(b\)在\(\pmod p\)意义下的逆元,太方便了

    这就引出了逆元的定义:

    若\(b*x \equiv 1 \pmod{p}\)且\(b,p\)互质,则\(x\)为\(b\)在\(\pmod p\)意义下的逆元 ,记作\(b^-1\)

  • 思路:

    算逆元一般有三种算法

    • 拓展欧几里得

      根据定义,若要求\(b\)在\(\pmod p\)意义下的逆元,就是求\(b*x \equiv 1 \pmod{p}\)中的x,转化成线性同余方程\(b*x+p*y=1\),接着就用拓欧跑一遍就好

    • 费马小定理

      若p是质数,则对于任意正整数b,有\(b^{p} \equiv b \pmod{p}\)

      所以\(b^{p-1} \equiv 1 \pmod{p}\) 把b继续拆得到

      \(b*b^{p-2} \equiv 1 \pmod{p}\)

      对照上面逆元定义,我们只用求\(b^{p-2} \pmod p\)

    • 线性递推

      设\(p=k*i+r\) 所以\(k=\left \lfloor \frac{p}{i} \right \rfloor,r=p \mod i\)

      所以\(k*i+r \equiv 0 \pmod p\) 同时乘以\(i^{-1},r^{-1}\)

      \(k*r^{-1}+i^{-1} \equiv 0 \pmod p\)移项

      \(i^{-1} \equiv -k*r^{-1} \pmod p\)

      \(i^{-1} \equiv -\left \lfloor \frac{p}{i} \right \rfloor*{(p \mod i)}^{-1}\pmod p\)

      我们把所有的逆元存在inv[]数组里,那么

      inv[i]=-((p/i)*inv[p%i]%p);
      while(inv[i]<0)inv[i]+=p;

      或者更优的写法

      inv[i]=(ll)(p-(p/i))*inv[p%i]%p;

      当然inv[1]=1;

  • 代码:

    • 拓欧+费马小定理

include

include

include

include

include

define LL long long

using namespace std;

LL mod(LL a,LL b)

{

if(a<b)return a;

if(a==b)return 0;

else return a-a/b*b;

}

LL pow_mod(LL a, LL b, LL p){//a的b次方求余p

LL ret = 1;

while(b){

if(b & 1) ret = mod((ret * a) ,p);

a =mod((a * a) ,p);

b >>= 1;

}

return ret;

}

LL Fermat(LL a, LL p){//费马求a关于b的逆元

return pow_mod(a, p-2, p);

}

void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){

if (!b) {d = a, x = 1, y = 0;}

else{

ex_gcd(b, mod(a,b), y, x, d);

y -= x * (a / b);

}

}

LL inv(LL t, LL p){//如果不存在,返回-1

LL d, x, y;

ex_gcd(t, p, x, y, d);

return d == 1 ? (mod(x,p) + p) % p : -1;

}

int main()

{

int op;

LL a,p;

cin>>a>>p;

for(int i=1;i<=a;i++)cout<<inv(i,p)<<endl;

return 0;

}

```

  • 线性递推
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <cmath>
#deinfe ll long long
using namespace std;
const int maxn=3000005;
int n,p;
ll inv[maxn];
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;
return ;
}
inline void make_inv(){
printf("1\n"); //inv[1];
for(register int i=2;i<=n;i++){
inv[i]=-((p/i)*inv[p%i]%p);
while(inv[i]<0)inv[i]+=p;
printf("%lld\n",inv[i]);
}
return ;
}
int main()
{
read(n),read(p);
inv[1]=1;
make_inv();
return 0;
}

luogu题解 P3811 【【模板】乘法逆元】的更多相关文章

  1. 【洛谷P3811】[模板]乘法逆元

    乘法逆元 题目链接 求逆元的三种方式: 1.扩欧 i*x≡1 (mod p) 可以化为:x*i+y*p=1 exgcd求x即可 inline void exgcd(int a,int b,int &a ...

  2. 【ZOJ 3609】Modular Inverse 最小乘法逆元

    The modular modular multiplicative inverse of an integer a modulo m is an integer x such that a-1≡x  ...

  3. 题解 P3811 【【模板】乘法逆元】

    P3811 [模板]乘法逆元 一个刚学数论的萌新,总结了一下这题的大部分做法 //一.费马小定理+快速幂 O(nlogn) 64分 #include<cstdio> using names ...

  4. 逆元-P3811 【模板】乘法逆元-洛谷luogu

    https://www.cnblogs.com/zjp-shadow/p/7773566.html -------------------------------------------------- ...

  5. luogu P3811 【模板】乘法逆元

    题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下的逆元. 输入输出样例 输入样 ...

  6. P3811 【模板】乘法逆元

    P3811 [模板]乘法逆元 线性递推逆元模板 #include<iostream> #include<cstdio> #include<cstring> #def ...

  7. [洛谷P3811]【模板】乘法逆元

    P3811 [模板]乘法逆元 题意 求1-n所有整数在模p意义下的逆元. 分析 逆元 如果x满足\(ax=1(\%p)\)(其中a p是给定的数)那么称\(x\)是在\(%p\)意义下\(a\)的逆元 ...

  8. 模板【洛谷P3811】 【模板】乘法逆元

    P3811 [模板]乘法逆元 给定n,p求1~n中所有整数在模p意义下的乘法逆元. T两个点的费马小定理求法: code: #include <iostream> #include < ...

  9. 洛谷 P3811 【模板】乘法逆元

    P3811 [模板]乘法逆元 题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下 ...

随机推荐

  1. Qt网络获取本机网络信息

    下面我们就讲解如何获取自己电脑的IP地址以及其他网络信息.这一节中,我们会涉及到网络模块(QtNetwork Module)中的QHostInfo ,QHostAddress ,QNetworkInt ...

  2. cache magic对pms模块的cache访问模式分析结果

    其中43.184的命中率只有不到70%,是要分析的对象:3.189是命中率98%左右,是做参考的对象. 基本统计:可以知道43.184的update和delete操作占总操作的比例要比3.189打不少 ...

  3. OpenWrt下如何配置网络?

    答: 使用uci进行配置,示例如下: uci get network.wan.ifname (笔者得到eth1) uci set network.wan.ifname=ethx (如: uci set ...

  4. 【Linux命令】find命令

    [find命令] 说明:find命令用来在指定目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件.并且将查 ...

  5. LC 926. Flip String to Monotone Increasing

    A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possibly 0), ...

  6. chrome新版本flash无法在http网站上运行的解决办法

    最近遇到一个问题,就是用chrome浏览器打开网站后台以后,使用flash插件上传文件失败,提示flash初始化失败,于是打开chrome的内容设置,准备启用flash功能,打开浏览器,在地址栏中输入 ...

  7. hibernate关联总结

    在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率! 配置一对多与多对一,这种叫“双向关联” 只配置一对多,  ...

  8. [Navicat]把1个库的数据迁移到另1个库--数据库备份

    需求: 将autotest库中所包含的所有表,从连接centOS7复制1份至localhost.autotest 操作步骤: 1.将centOS7.autotest库中表结构及表数据转为sql语句:c ...

  9. 深入解读TCP/IP

    虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Microsoft都有各自的 ...

  10. Redis之快速入门与应用[教程/总结]

    内容概要 因为项目中用户注册发送验证码,需要学习redis内存数据库,故而下午花了些时间进行初步学习.本博文性质属于对今日redis学习内容的小结.在看本博文前或者看完后,可以反问自己三个问题:Red ...