逆元

在分数取模时总会用到逆元运算
一般只需要求出分母关于取模的逆元即可
然后分子乘以该逆元就是分数取模的结果

在模运算中

(a +  b) % p = (a%p +  b%p) %p  (对)
(a  -  b) % p = (a%p  -  b%p) %p  (对)
(a  *  b) % p = (a%p *  b%p) %p  (对)
(a  /  b) % p = (a%p  /  b%p) %p  (错)

对于除法的模运算不适合,所以需要定义一个新的东西来求除法模运算,这个东西就是逆元

定义:

(a/b)(mod p)=(ainv[b])(mod p)或者ab≡1(mod P)`
inv[b]就是b的逆元 a就是b的逆元,或者ab或为逆元

则根据定义可知

除以一个数再取模等同于乘以这个数的逆元再取模

但是我们不能直接说一个数的逆元是多少,
应该这么说: 一个数 x 在模 p 的条件下的逆元是多少
比如2 * 3 % 5 = 1,那么3就是2关于5的逆元,或者说2和3关于5互为逆元
(a*inv[b])%p,inv[b]就是a关于p的逆元
条件:a与p互为质数,a才有关于p的逆元

转换除法模运算

根据取模运算

(a +  b) % p = (a%p +  b%p) %p  (对)

(a  -  b) % p = (a%p  -  b%p) %p  (对)

(a  *  b) % p = (a%p *  b%p) %p  (对)

(a  /  b) % p = (a%p  /  b%p) %p  (错)

(a / b) % p = (a * inv(b) ) % p = (a % p * inv(b) % p) % p

求逆元

方法1--费马小定理:

如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。



a^(p-1) ≡1 (mod p)
两边同除以a
a^(p-2) ≡1/a (mod p)
a^(p-2) ≡ inv(a) (mod p)
inv(a) = a^(p-2)
即可求出a的逆元时a^(p-2)

用快速幂求,复杂度O(logn)

LL pow_mod(LL a, LL b, LL p){//a的b次方求余p
    LL ret = 1;
    while(b){
        if(b & 1) ret = (ret * a) % p;
        a = (a * a) % p;
        b >>= 1;
    }
    return ret;
}
LL Fermat(LL a, LL p){//费马求a关于b的逆元
        return pow_mod(a, p-2, p);
}
int main(){
    LL a, p;
    while(~scanf("%lld%lld", &a, &p)){
        printf("%lld\n", inv(a, p));
    }
}

费马小定理

方法2--扩展欧几里得

ax + by = 1

如果ab互质,有解
这个解的x就是a关于b的逆元
y就是b关于a的逆元

两边同时求余b
ax % b + by % b = 1 % b
ax % b = 1 % b
a
x = 1 (mod b)
反之可证明y

用扩展欧几里得模板求

#include<cstdio>
typedef long long LL;
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,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 ? (x%p+p)%p : -1;
}
int main(){
    LL a, p;
    while(~scanf("%lld%lld", &a, &p)){
        printf("%lld\n", inv(a, p));
    }
}

例题:

hdu1576
求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。

因为9973为质数,作为p
本题要求b的逆元,设c为b的逆元
(A/B)mod P = (A/B)1mod p = (A/B)BC mod p=AC(mod p);
利用费马小定理得到C=B^(p-2)
答案就是(AC)%p=(A%pC%p)%p

所以先利用费马小定理得到逆元,利用快速幂
再代入等式求出答案

转载于:https://www.cnblogs.com/Emcikem/p/11342346.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值