乘法逆元

乘法逆元

​ 在组合计数中,由于答案过大,需要取模。比如计算 C n m C_n^m Cnm.

​ 为了求出 a b ≡ x ( m o d   m ) \frac a b \equiv x (mod\ m) bax(mod m)中的 x x x,就需要求出 b b b的逆元 b − 1 b^{-1} b1,因为 b b − 1 ≡ 1 bb^{-1} \equiv 1 bb11,所以 a b ≡ a b − 1 \frac a b \equiv ab^{-1} baab1

1-费马小定理

​ (的推论) a p ≡ a ( m o d   p ) a^p \equiv a (mod\ p) apa(mod p),当 p p p为质数且 ( a , p ) = 1 (a,p)=1 (a,p)=1

​ 这样 a p − 2 = a − 1 a^{p-2}=a^{-1} ap2=a1,用快速幂求就好。

ll Reverse(ll op){
    ll poi = mod - 2, base = op, res = 1;
    while(poi){
        if(poi&1)
            res = (res*base) % mod; //在mod>INT_MAX时不适用。
        base = (base*base) % mod;
        poi >>= 1;
    }
    return res;
}
2-扩展欧几里得算法

a x + b y = ( a , b ) ax+by=(a,b) ax+by=(a,b)一定有解。

​ 又设 b x ′ + ( a % b ) y ′ = ( a % b , b ) = ( a , b ) bx'+(a\%b)y'=(a\%b,b)=(a,b) bx+(a%b)y=(a%b,b)=(a,b)

​ 则 a x + b y = b x ‘ + ( a % b ) y ’ = b x ′ + ( a − b ∗ ⌊ a / b ⌋ ) y ’ ax+by=bx‘+(a\%b)y’=bx'+(a-b*\lfloor a/b \rfloor)y’ ax+by=bx+(a%b)y=bx+(aba/b)y

a x + b y = a y ′ + b ( x ′ − ⌊ a / b ⌋ y ′ ) ax+by=ay'+b(x'-\lfloor a/b \rfloor y') ax+by=ay+b(xa/by)

​ 因此 x = y ′ x=y' x=y y = x ′ − ⌊ a / b ⌋ y ′ y=x'-\lfloor a/b \rfloor y' y=xa/by

​ 只要求解 b x ′ + ( a % b ) y ′ = ( a , b ) bx'+(a\%b)y'=(a,b) bx+(a%b)y=(a,b),将 x ′ , y ′ x',y' x,y带入即可求出 x , y x,y x,y

​ 这样,我们可以像欧几里得算法一样不断减小系数的规模。只要递归地求解更小规模的方程,最后回溯时将解依次带回就好。递归终点是当 b i = 0 b_i=0 bi=0时,这时 ( a i , b i ) = a i = ( a , b ) (a_i,b_i)=a_i=(a,b) (ai,bi)=ai=(a,b) a i x i + b i y i = ( a i , b i ) a_ix_i+b_iy_i=(a_i,b_i) aixi+biyi=(ai,bi)一组解是 x i = 1 , y i = 0 x_i=1,y_i=0 xi=1,yi=0

​ 当 ( a , b ) = 1 (a,b)=1 (a,b)=1时, a x + b y = 1 ax+by=1 ax+by=1可用来求解 b b b在模 a a a意义下的逆元 y y y,或者 a a a在模 b b b意义下的逆元 x x x.

void exEuclid(ll a, ll b, ll &d, ll &x, ll &y){
    if(!b)
    	d=a, x=1, y=0;		//d就是gcd
    else{
        exEuclid(b, a % b, d, y, x);
        y -= x * (a / b);	//x=y', y=x' - y'*(a/b)
    }
}

​ 复杂度与辗转相除法相同 O ( l o g   a b ) O(log\ ab) O(log ab),因为每一次都使较大的数减小一半以上。

3-线性递推法

​ 需要 m o d mod mod是质数。

​ 设 m o d = k ∗ i + r ≡ 0 mod = k*i+r\equiv 0 mod=ki+r0

​ 两边同乘 i − 1 r − 1 i^{-1}r^{-1} i1r1

k ∗ r − 1 + i − 1 ≡ 0 k*r^{-1}+i^{-1}\equiv 0 kr1+i10

i − 1 ≡ m o d − k r − 1 i^{-1}\equiv mod-kr^{-1} i1modkr1

​ 其中 k = ⌊ m o d / i ⌋ k=\lfloor mod/i \rfloor k=mod/i r = m o d % i r = mod\%i r=mod%i

rev[1]=1;
for(int i=2; i<mod; i++)	
    rev[i]=(mod - mod/i)*rev[mod%i]%mod;
例题:[SCOI2010]生成字符串

许多需要求组合数的题目中都需要求逆元。本题求解的思路与求卡特兰数的推导过程非常相似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值