逆元的定义,性质,求解方法与例题

您所在的位置:网站首页 生成元的求法 逆元的定义,性质,求解方法与例题

逆元的定义,性质,求解方法与例题

#逆元的定义,性质,求解方法与例题| 来源: 网络整理| 查看: 265

文章目录 一、定义二、作用及证明作用.计算除法的模 (a/b) mod n证明: 三、求解方法1.扩展欧几里得算法2.欧拉定理与费马小定理(快速幂求法)3.线性递推(逆元打表) 四、性质(映射关系)1.性质2.证明 五、例题·瞬间移动1.分析2.代码

一、定义

若整数a、b满足同余方程a∗b≡1(mod n) ,那么a,b互为模n意义下的逆元

逆元存在的充要条件为gcd(a,n)为1.

二、作用及证明 作用.计算除法的模 (a/b) mod n

除法不可以使用之前分部的策略,否则结果将会产生问题。

证明:

1.若 ( a / b ) mod n = m,左右同时乘以 b 由于m 与(a/b)是关于模n同余的, 根据同余式的性质: 若a≡b (% p),则对于任意的c,都有 (a * c) ≡ (b * c) (%p)

所以此时有: a % n = (m * b)% n 2.若存在x,可使得 a * x = m%n,将x与上式的左右相乘 根据相同的性质,得: (a * x)% n = (m * x * b)% n = m % n 也就意味着 (b * x)%n = 1; 即 x,b互为模n意义下的逆元

那么证得通过a 乘上 b 对模n的逆元可以求出(a/b) mod n

三、求解方法 1.扩展欧几里得算法

扩展欧几里得算法 a ∗ x ≡ 1 ( mod n) 可以化为:a* x = k * n + 1 a * x + (-k )* n = 1 即 a * x + n * k = 1 满足扩展欧几里得的格式,若此时gcd (a,n)!=1,那么此时方程无解,即不存在逆元

若满足gcd (a,n)的条件,根据扩展欧几里得算法就可以直接求出一个x,当然此时的解也不唯一,不过我们一般都是使用exgcd所得的那个特解。 对exgcd所得的那个解进行处理,保证其为一个正整数。 x%mod+mod)%mod

typedef long long LL; LL exgcd(LL a,LL b,LL &x,LL &y)//扩展欧几里得算法 { if(b==0) { x=1,y=0; return a; } LL ret=exgcd(b,a%b,y,x); y-=a/b*x; return ret; } LL getInv(int a,int mod)//求a在mod下的逆元,不存在逆元返回-1 { LL x,y; LL d=exgcd(a,mod,x,y); return d==1?(x%mod+mod)%mod:-1; } 2.欧拉定理与费马小定理(快速幂求法)

费马小定理: 若p为素数,则有a^(p-1) ≡ 1(mod p)

欧拉定理(费马小定理的推广): 若a、p互素,则有a^φ( p) ≡ 1(mod p)

两个定理的证明

在费马小定理中,a ^ (p-2)∗a ≡ 1(mod p) a ^ (p-2)就是a在mod p意义下的逆元;

在欧拉定理中,a^(φ( p)-1)* a ≡ 1(mod p) a^(φ( p)-1)就是a在mod p意义下的逆元

那么我们就转化为了求快速幂的问题。至于求欧拉函数的方法会在后面讲。

总之只要p为素数,就可以使用费马小定理直接快速幂求解; 若不为素数,就需要先求出p的欧拉函数再进行快速幂求解。

3.线性递推(逆元打表)

给定模 p 和 n,可以在线性时间内求出1 到 n 对 p 取模的逆元。

p为一个不算太大的质数

已知边界条件为 inv[ 1 ] = 1; 目标是求 i 模 p 的逆元 p 可以表示为 k * i + r; 其中存在关系: k = p / i; r = p % i;

根据 p = k * i + r 可以得到:( k * i + r) ≡ 0 (mod p) 对左右同时乘以(r ^ -1)*(i ^ -1), 可以得到:k∗(r ^ -1)+(i ^ -1)≡0 (mod p) 可以转化为:(i ^ -1)≡(−k∗(r ^ -1))(mod p) 即inv[ i ] = (-k * inv[ r ] )(mod p)=(−p/i ∗ inv[p%i])(mod p)

此时我们就可以用inv[p%i] 的结果来计算inv[ i ]的结果。

void getInv(int mod)//线性递推求逆元 { inv[1]=1; for(int i=2;i //组合计算的快速方法 ll t1=1,t2=1; for(int i = b ; i>=(b-a+1) ;i--)t1 = t1*i%mod; for(int i = a ; i>=1 ;i--)t2 = t2*i%mod; return t1*inv(t2,mod)%mod; } int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ if(n>m)swap(n,m); printf("%d\n", C(m-2,n+m-4) ); } return 0; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3