逆元:

如果满足公式,则有a 是 b的逆元同时b也是a的逆元。

逆元的应用:

设c为b在对m取余的意义下的逆元;

在求解公式 (a / b) % m的时候,如果b可能会非常的大,所以会出现爆精度的问题,这个时候就需要将除法转换成乘法来做,即:

(a / b )  % m = (a * c)%m。

逆元的求法:

一、扩展欧几里得求逆元

复杂度:O(logn)(实际就是斐波那契数列)

将公式(b、p已知)   a∗b≡1(mod p)   转换为   a∗b+k∗p=1  则有a为b对p取余意义下的逆元,且只有当a与p互质是逆元才存在

注意:只要存在逆元就可以求,适用于逆元个数不多,但是mod很大的时候。

附一个百度百科的例子加深一下理解:

代码:

/*
Time:2018/8/31
Writer:Sykai
Function:利用扩展欧几里得求逆元
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
typedef long long ll;
typedef pair<int,int> P; //公式a∗b+k∗p=1中a即是a,p即是b
ll exgcd(ll a,ll b,ll& x,ll& y)
{
if(b == )
{
x = ;
y = ;
return a;
}
ll res = exgcd(b, a%b, y, x);
y -= a/b*x;
return res;
}
//公式a∗b+k∗p=1中a即是a,p即是mod
ll getInv(int a,int mod)//求a在mod下的逆元。如果不存在就返回-1
{
ll x,y;
ll res = exgcd(a,mod,x,y);
return res = ? (x%mod + mod)%mod:-;//return res = 1?(x + mod)%mod : -1;
} int main()
{
ll a = ;
printf("%lld\n",getInv(a,MOD));
return ;
}

二、费马小定理求逆元

复杂度:O(logn)

费马小定理: 假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p)。

a*a^(p-2) ≡ 1 (mod p),则有a^(p-2)是a的对p取余时候的逆元

注意:当p是素数的时候一般选用费马小定理来求逆元。

代码:

/*
Time:2018/8/31
Writer:Sykai
Function:利用费马小定理求逆元
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
typedef long long ll;
typedef pair<int,int> P; ll qpow(ll a,ll b)//求a*a^(p-2) ≡ 1 (mod p)中a^(p-2)
{
ll res = ;
while(b)
{
if(b&)
res = res * a % MOD;
a = a * a % MOD;
b >>= ;
}
return res;
} ll getInv(ll a,ll mod)
{
return qpow(a,mod-);
} int main()
{
int a = ;
printf("%lld\n",getInv(a,MOD));
return ;
}

三、递推求逆元

复杂度:O(n)

注意:

1、mod需要是质数,求得是1~N关于mod的逆元。

2、适用于mod不是太大,且被多次调用。

3、程序开始前需要预处理打表。

代码:

/*
Time:2018/8/31
Writer:Sykai
Function:线性求逆元
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
typedef long long ll;
typedef pair<int,int> P;
ll inv[maxn];//数组的大小需要根据实际情况来调整 void getInv()
{
inv[] = ;
for(int i = ; i < maxn; i++)
inv[i] = (MOD-MOD/i)*inv[MOD%i]%MOD;
} int main()
{
getInv();
printf("%lld\n",inv[]);
return ;
}

四、递归求逆元

复杂度:O(logn)

注意:mod需要是素数(中国剩余定理中不太好用)

/*
Time:2018/8/31
Writer:Sykai
Function:递归求逆元
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
typedef long long ll;
typedef pair<int,int> P;
ll inv[maxn];//数组的大小需要根据实际情况来调整 ll getInv(ll x)
{
if(x == ) return ;
return (MOD-MOD/x)*getInv(MOD%x)%MOD;
} int main()
{
printf("%lld\n",getInv());
return ;
}

五、求阶乘的逆元

代码:(不确定怎么用)

/*
Time:2018/8/31
Writer:Sykai
Function:递归求逆元
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <set>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
typedef long long ll;
typedef pair<int,int> P;
ll inv[maxn];//数组的大小需要根据实际情况来调整
ll fac[maxn+];//阶乘数组
ll qpow(ll a,ll b)
{
ll res = ;
while(b)
{
if(b&)
res = res * a % MOD;
a = a * a % MOD;
b >>= ;
}
return res;
} int main()
{
inv[maxn] = qpow(fac[maxn],MOD-);
for(ll i = maxn-; i>=; i--)
{
inv[i] = (inv[i+]*(i+))%MOD;
}
return ;
}

参考博客:

https://blog.csdn.net/baidu_35643793/article/details/75268911

https://blog.csdn.net/xiaoming_p/article/details/79644386

逆元Inv(模板+应用)的更多相关文章

  1. 生成树计数 lighting 最终决定用这个模板! (有逆元的模板)

    #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> # ...

  2. 逆元(inv)

    当求解公式:(a/b)%m 时,因b可能会过大,会出现爆精度的情况,所以需变除法为乘法: 设c是b的逆元,则有b*c≡1(mod m): 则(a/b)%m = (a/b)*1%m = (a/b)*b* ...

  3. 生成树计数模板 spoj 104 (不用逆元的模板)

    /* 这种题,没理解,只是记一记如何做而已: 生成树的计数--Matrix-Tree定理 题目:SPOJ104(Highways) 题目大意: *一个有n座城市的组成国家,城市1至n编号,其中一些城市 ...

  4. 牛客多校第六场 C Generation I 组合数学 阶乘逆元模板

    链接:https://www.nowcoder.com/acm/contest/144/C来源:牛客网 Oak is given N empty and non-repeatable sets whi ...

  5. 逆元知识普及(扫盲篇) —— from Judge

    watch out 本文是博主的 csdn 上搬过来的,格式有点崩,看不下去的可以去 博主的 csdn上看(上面 格式会好很多,并且有些公式也用 $\LaTeX$  update 上去了) 最近有点颓 ...

  6. NOIP经典基础模板总结

    date: 20180820 spj: 距离NOIP还有81天 目录 STL模板: priority_queue 的用法:重载<,struct cmpqueue 的用法 stack 的用法vec ...

  7. 【牛客小白月赛6】F 发电 - 树状数组&快速幂&逆元

    题目地址:https://www.nowcoder.com/acm/contest/136/F 树状数组.快速幂.逆元的模板运用: #include<iostream> #include& ...

  8. poj 1006中国剩余定理模板

    中国剩余定理(CRT)的表述如下 设正整数两两互素,则同余方程组 有整数解.并且在模下的解是唯一的,解为 其中,而为模的逆元. 模板: int crt(int a[],int m[],int n) { ...

  9. [OI笔记]三种逆元的求法

    其实这篇博客只是搬运一下我之前(大概是NOIP那会)写在word里的笔记- 下面直接复制原话,题目是洛谷上求逆元的模板题:https://www.luogu.org/problemnew/show/P ...

随机推荐

  1. 最简单的基于FFmpeg的移动端样例:Android HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  2. 3730 无线网络发射选址[NOIP 0214 day2 T1]

    3730 无线网络发射选址  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题解  查看运行结果     题目描述 Description 随着智能手机的日 ...

  3. 41. extjs--combobox下拉列表的triggerAction

    转自:https://icrwen.iteye.com/blog/939247 一般combobox的store先load加载数据,然后combobox的mode设置为local,则不会每次下拉列表都 ...

  4. Mysql 数据库编码问题

    数据库建表后,插入数据,如果数据位汉子,将提示错误:“incorrect string value....”. 解决方法:改变数据库编码 第一种方法:改变database 编码: alter data ...

  5. PCB 自动发送邮件---加入表格实现方法

    先看一下手动发送邮件内容加入表格操作(下图所示),直接复制Excel内容,再粘贴到邮件内容中,就是这么便捷,如果我们想自动发送邮件,也实现同样的效果如果实现呢,在这里介绍2种方法: 一.读取Excel ...

  6. bzoj2431: [HAOI2009]逆序对数列(前缀和优化dp)

    2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2312  Solved: 1330[Submit][Stat ...

  7. codevs1040统计单词个数(区间+划分型dp)

    1040 统计单词个数 2001年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold   题目描述 Description 给出一个长度不超 ...

  8. 如何获取<a>标签的Id

    案例: <a id='213' href='javascript:void(0);'onclick=DealFun(this.Id);>删除</a> 解决方案: functio ...

  9. 【NOIP练习赛】学习

    [NOIP练习赛]T3.学习 Description 巨弱小 D 准备学习,有 n 份学习资料给他看,每份学习资料的 内容可以用一个正整数 ai 表示.小 D 如果在一天内学习了多份资料, 他只能记住 ...

  10. mysql多表查询 查询排序

    有 ask 问题表  和 answer回答表  回答表中的ask_id和 ask表中的id对应 1.查询 /*查询回答了的 */select a.id,a.title,count(b.ask_id) ...