逆元 -- 逆元和相关性质 覆盖盲点

题记: 逆元素是指可以取消另一给定元素运算的元素, 本文中主要谈及与算法竞赛的逆元.

         在下才疏学浅, 如有纰缪和遗漏还望指出.

逆元

前置知识: 代数系统, 幺元.

逆元(Inverse element)的定义: 在代数系统<S, *>中, 若存在元素a,b ∈ S 且 a * b = 幺元e, 则元素a称为b的左逆元, 元素b称为a的右逆元. 若元素x同时为另一个元素y的左逆元和右逆元则称x是y的逆元. 同理y亦是x的逆元.

 

逆元的用处:

算法竞赛中经常会出现模余运算, 模余的加丶减丶乘法比较简单: a+b(mod p) = (a+b) mod p

           a-b(mod p) = (a-b+p) mod p

           a*b(mod p) = a * b mod p -- 考虑*的优先级高于%故没加()

 

但是对于模余除没接触过逆元的同学就莫名慌张了,除法会不会出现问题呢? 举个栗子: 最简单的C(n, 3) 即 n(n-1)(n-2) / 6 初学者的想法可能是先将n(n-1)(n-2)的模余乘法结果S算出来再除6但我们知道模余后S不一定会被6整除(这里一定出现的差错~), 那么怎么办呢? 于是聪明的人类发现了逆元这个东西. 先介绍性质: 在模余自然数域中, 除一个数等于乘以它的乘法逆元. 好! 这就是逆元的最原始用处. (但是你说是就是, 快给个证明xD)好, 那么证明如下:

如果 b*a = 1(mod p)

则 b = a^(-1) -- b是a的逆元

      则 c / a = c * a^(-1) = c * b (mod p)

于是上述性质得到了证明。

 

求逆元的方法: 求解逆元主要有两种方式,扩展欧几里得算法以及基于费马小定理的快速幂算法。

费马小定理

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

于是容易得到 a* a^(p-2)≡1(mod p)故 a^(p-2)为a在mod p下的逆元

typedef long long ll;
const ll mod = p;

//快速幂 求x的n次幂
ll mod_pow(ll x, ll n){
    ll res = 1; // result
    while(n){
        if(n&1) res = res*x%mod;
        x = x*x%mod; n>>=1;
    }
    return res;
}

//求x在mod p下的逆元
ll mod_reverse(ll x){
    return mod_pow(x, mod-2); 
}

ps:在一般情况下,如果快速幂中n过大,可以将n%φ(mod)来达到降幂 --不理解请参考欧拉定理

扩展欧几里得

想法是ax+by=gcd(x,y) 若 x*(x^-1) mod p = 1 可以写成  x*a= p*b+1那么 x*a-p(y)*b=1就是说可以套用扩展欧几里得来求出a,b。   a即为x在mod p下的逆元

​
long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if (b==0) { x=1,y=0; return a; }
    long long d=exgcd(b,a%b,x,y);
    long long tmp=x;
    x=y;
    y=tmp-a/b*y;
    return d;
}

​//求x在mod p的逆元
long long mod_reverse(ll x){
    long long a, b;
    long long g = exgcd(x, p, a, b);
    return (a/g%p+p)%p;
}

关于逆元的预处理, 逆元可以在O(n)的时间复杂度预处理, 如果已经处理出阶乘表可以在O(1)的时间内求解,对于未进行任何预处理的逆元可以在(plogp+N^(-1/2))的时间内及逆行求解p代表的是逆元中不同质数的个数。

逆元的预处理

typedef long long ll;
const ll mod = ?;
ll r[MAX_N];

void init(){
    r[1] = 1;
    for(int i=2; i<MAX_N; i++) r[i] = r[mod%i] * (mod-mod/i)%mod;
}

证明:

p是模数,i是待求的逆元,我们求的是i−1i−1在mod p意义下的值 
p=k∗i+rp=k∗i+r令 r < i,则k=p/i,r=p%i 
k∗i+r≡0(modp)k∗i+r≡0(mod p) 
k∗r−1+i−1≡0(mod p)k∗r−1+i−1≡0(mod p) 
i−1≡−k∗r−1(mod p)i−1≡−k∗r−1(mod p) 
i−1≡−p/i∗inv[p mod i]i−1≡−p/i∗inv[p mod i] 

说白了就是:inv[i]=-(mod/i)*inv[i%mod] 
 

未完待续

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值