浅析逆元&逆元的蛋用(完全版)
来源:互联网 发布:52mac网可靠吗 编辑:程序博客网 时间:2024/05/17 04:49
- 逆元
- 某些性质
- 演算一下
- 逆元的蛋用
- 逆元这东东怎么求
- 方法一
- code
- 方法二
- code
- 方法三
- 递归code
- 递推code
- 方法一
- said at the end
逆元
首先扯一点没有多大用的东西
在数论里面,我们通常不把倒数叫做倒数,而叫做逆元(纯属装13)
逆元的作用是非常非常大的,下面我们来看点easy的栗子
某些性质
前面三个都是对的(不需要证明~) 但是——
上面的÷是整除
不等号左面是等于6的,而不等号右面是等于2的,明显不相等
演算一下
这是不是说我们对除法下的大数模操作就毫无办法了?答案是no
为了方便,先来看看一些小学or初中级别的东东
比如说有条等式
然后我再加一个条件
对于①式,我们就把x看成
这时候,我们不把x看成倒数。这时的x为a关于p的逆元
(注意,当且仅当
又是一个栗子
在这里,5和
(注意一点,除了α=5,没有其他整数α满足3α≡1(mod 7),可以手玩试试,所以说逆元是唯一的)
逆元的蛋用
前面说了一些,相信逆元的定义了应该很好懂
我们不妨把x的逆元用inv(x)来表示,那么对于除法——
难搞的除法瞬间变成了乘法,秒变水了很多
逆元这东东怎么求
方法一
基础数论里面有两条著名的定理:欧拉定理和费马小定理
欧拉定理:(当(a,n)=1时成立)
费马小定理:(当(a,p)=1且p为质数时成立) (我难道会告诉你我两个都不会证明吗……)
很明显,费马小定理是可以从欧拉定理推过来的
当p为质数时
既然我们在谈论逆元,就把费马小定理两边同除以一个p
attention to到一点就是
这时拍拍自己的脑袋,看一看上面,我们突然发现应该把
所以——
我们可以用快速幂来求a的逆元,时间复杂度
code
long long inv(long long a,long long p){ long long t=1,b=p-2; while (b) { if ((b%1)==1)t=t*a%p; a=a*a%p; b/=2; } return t;}
通常题目会让你求10^9+7取模,这方法可以说快到飞起
方法一用快速幂求逆元,容易上手,对于OI大多数的题目,已经足够
方法二
逆元还可以用扩展欧几里得算法来求,怎么求?一步一步来
首先要知道一个概念:贝祖定理,他的描述是
对于a,b>0且a,b∈N,必然存在整数x和y,使得ax+by=gcd(a,b)
比如我们现在要求a关于p的逆元(条件是a和p互质且p是质数)
代入贝祖定理,则
给上面那个式子做点操作,两边各模一个p,得到
∴x是a关于p的逆元(其实y也是p关于a的逆元,可证,同理)
这里用扩展欧几里得exgcd(a,p,x,y),求出的x即为a的逆元
code
void exgcd(long long a,long long b,long long &x,long long &y){ if (b==0) { x=1; y=0; return; } exgcd(b,a%b,y,x,d); y-=x*(a/b);}long long inv(long long a,long long b){ long long x,y; exgcd(a,b,x,y); return (x%p+p)%p;}
扩展欧几里得可谓比较牛,优点是用途多,能求gcd能求逆元能解线性方程
对于广大OIers是把利器,学会是必须的
方法三
最后一种方法更简单更好打更好理解:递归
先来一发证明(网上找的)
有了这个等式,我们就可以用递归来求inv(a)了
递归出口inv(1)=1,因为1的逆元就是1
递归code
long long inv(long long a,long long p) //注意a要小于p,先把a%p一下 { return a==1?1:(p-p/a)*inv(p%a,p)%p;}
是不是短到爆炸?
因为
这种思想比费马小定理、扩展欧几里得优的地方是,他能用
只不过把递归的式子改成递推而已
递推code
void init(){ inv[1]=1; for(int i=2;i<=n;i++) { inv[i]=(p-p/i)*1ll*inv[p%i]%p; }}
这是方法三,个人感觉方法三在某些题目里更好用一些
易理解,码量低,时间复杂度也低,还能快速预处理,interesting——
said at the end
三种求逆元的方法,各有各自的优点
方法一,适合不太会证明但很会打代码的coder
方法二,数学思维强且脑子转得快的小牛用吧
方法三则属于比较懒、懒得打键盘的OIers
无论哪种方法,能求逆元的方法都是好方法
又涨了不少姿势
thanks for your watching!
- 浅析逆元&逆元的蛋用(完全版)
- 逆元浅析
- C ++友元的浅析(一)
- 逆元的使用
- 逆元的学习
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 【 逆元 】
- 【逆元】
- 逆元
- 【逆元】
- 逆元
- 常见的动态规划问题分析与求解
- 个人随笔和笔记:响应式布局meta声明
- iOS时间戳
- map reduce lambda 区别 用法 结合使用
- C++资源
- 浅析逆元&逆元的蛋用(完全版)
- centos下通过终端查找存储指令的文件名
- 测试小白应该会的MySQL操作
- Linux下Rsync+Inotify-tools实现数据实时同步
- 聚合数据手机验证码在ThinkPHP中实现
- 响应式布局个人随笔
- 对向量的处理,在控制板显示出按钮42
- JVM系列四:生产环境参数实例及分析【生产环境实例增加中】
- 小白学习Machine Learning in Action-机器学习实战------Python基础