求乘法逆元的几种方法

(数学渣,下面的文字可能有误,欢迎指教)
乘法逆元的定义貌似是基于群给出的,比较简单地理解,可以说是倒数的概念的推广。记a的关于模p的逆元为a^-1,则a^-1满足aa^-1≡ 1(mod p)

加减乘与模运算的顺序交换不会影响结果,但是除法不行。有的题目要求结果mod一个大质数,如果原本的结果中有除法,比如除以a,那就可以乘以a的逆元替代。

在mod p的运算中,a存在乘法逆元当且仅当a与p互质。一般题目给的是一个大质数,所以只要a不是p的倍数,就以求乘法逆元。

目前了解到的求法有三种:
1.扩展欧几里得。aa^-1≡ 1(mod p),可以转换为aa^-1 + py = 1,即是扩展欧几里得所能解的ax + by = gcd(a, b)。最常用的解法。

int x, y;
int extgcd(int a, int b, int &x, int &y)
{
    if (b == 0){
        x = 1;
        y = 0;
        return a;
    }
    int gcd = exgcd(b, a % b, x, y);
    int tmp = x;
    x = y;
    y = tmp - (a/b) * y;
    return gcd;
}

/*
求解ax+by=gcd(a,b),亦即ax≡1(mod b)。函数返回值是a,b的最大公约数,而x即a的逆元。
注意a, b不能写反了。
*/

2.由费马小定理a^(p-1)≡ 1(mod p)(p为素数),稍作变形即是 aa^(p-2)≡ 1(mod p),是不是发现了,a^(p-2)即是a的逆元,这个可以用快速幂来求。

3.网上看到的一个很厉害的o(n)的递推,求前n个逆元,不知道是怎么推出来的,但是可以简单地证明一下正确性(要求所mod p为素数)。

首先,1的逆元是1,没什么疑问。
假设前i个数的逆元已经求出,那么
i^-1 = (p%i)^-1 * (p - [p/i]) % p。其中[]表示去尾取整。
(p%i)^-1其实就是(p-[p/i]i)^-1,然后我们左右乘以i,
ii^-1 = (p-[p/i]i)^-1 * ((i-1)p + p-[p/i]i) % p,
其实就是ii^-1 = k^-1 * ((i-1)p + k) % p = 0 + 1 = 1,这样就证完了=。=

//字体真糟糕。。

int[] inv = new int[MAXN];
inv[1] = 1;
for (int i = 2; i<MAXN; i++)
    inv[i] = inv[MOD%i]*(MOD-MOD/i)%MOD;

求乘法逆元的几种方法,布布扣,bubuko.com

时间: 2024-10-15 04:30:28

求乘法逆元的几种方法的相关文章

除法求模中求逆元的两种方法

今天下午还是有点闲的,不想刷题,不想补题,突然想起昨天的training 3里I题涉及到除法取模的问题,就来总结一下 首先对于模运算来说,是没有对于除法的取模的(即没有(a/b)%mod==a%mod/b%mod),但是在很多题目中都涉及到除法取模,所以就必须要了解或者掌握,对于除法取模以(a/b)%mod来说,我们首先需要得到b的逆元,根据逆元的定理 对于正整数和,如果有,那么把这个同余方程中的最小正整数解叫做模的逆元. 然后就是求逆元的两种方法. 第一种方法就是比较普遍的,也是挺基础的,就是

求Fibonacci数的三种方法和时间复杂度解析

题目: 定义Fibonacci数列如下: f(0)=1 f(1)=1 f(n)=f(n-1)+f(n-2), n>=2 输入n,用最快的方法求该数列的第n项. 解答一: 直接用公式写递归函数.很简单,很低效,就不写了.时间复杂度T(N) = T(N-1) + T(N-2); 也是f(n)本身,2^(n/2)<f(n)<2^n. 解答二: 用循环求,也很直接,效率很高了,时间复杂度是O(n). int f(int n) { if(n <= 1) return 1; int f0=1,

hdu1576(扩展gcd求乘法逆元)

A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7509    Accepted Submission(s): 5969 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1). Input 数据的第一行是一个T

求最大公约数的三种方法

一.最大公约数与最小公倍数 最大公约数,属于数论所探究的内容. 最大公约数可以通过下面的三种方法求出来. 最小公倍数呢,它与最大公约数的乘机为所求数之积. 比如求  x,y的最大公约数和最小公倍数 记住这个公式: x*y=最小公倍数*最大公约数 二.求最大公约数的三种方法 ①辗转相除法 算法流程图 int measure(int x, int y) { int z = y; while(x%y!=0) { z = x%y; x = y; y = z; } return z; } 运行结果: ②辗

HDU 1576 -- A/B (总结乘法逆元的几种求法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1576 A/B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7264    Accepted Submission(s): 5774 Problem Description 要求(A/B)%9973,但由于A很大,我们只给出n(n=A%99

费马小定理 求乘法逆元

//P3811 [模板]乘法逆元 #include<bits/stdc++.h> using namespace std; inline void write(long long X) { if(X<0) {X=~(X-1); putchar('-');} if(X>9) write(X/10); putchar(X%10+'0'); } long long qpow(long long n,long long m,long long mod) { long long ans=1;

(数论)简单总结求逆元的几种方法

逆元(Inverse element),如a?b≡1(modp),那么a,b互为模p意义下的逆元,则p|(a/c-b*c)(即a/c与b*c同余). 常用的求逆元方法有 1.费马小定理 若p为素数,且gcd(a,p)=1,则a^(p-1)≡1(mod p),即a*a^(p-2)≡1(mod p),故a的逆元为a^p-2. 2.拓展欧几里德算法(递推再回溯) 当gcd(A,B)|C时,可求二元一次方程Ax+By=C的整数通解. 3.逆元线性筛 递推公式:inv[i]=inv[p % i] * (p

新学一个 求乘法逆元的方法。

inv[x] = ( Mod - Mod / x ) * inv[Mod%x] % Mod 设Mod=px+q.  inv[x]=r px+q = 0  (mod  Mod) pxr+qr = 0 (mod Mod) p + qr = 0 (mod Mod) r=-p/q= -p*inv[q] = -(Mod/x)*inv[Mod % x] = (Mod - Mod/x) * inv[Mod % x].

求乘法逆元

由于在计算除法时,mod 运算不能直接加在除数被除数后,因此需要将 n / a (mod b )转化为 n * x (mod b ),以便于进行模运算.求 x 的过程就称为求逆元. 对于 a .b (a 与 b 互素)满足 n / a ≡ n * x (mod b ),则称 x 为 a 模 b 的逆元: 一般有两种求逆元的方式:扩展欧几里得求逆元和欧拉-费马定理求逆元: 1.扩展欧几里得求逆元: 见(欧几里得与扩展欧几里得): http://www.cnblogs.com/cenariusxz/