Learn the inverse element (extended Euclid, Fei Xiaoma's theorem, linear solution)

Inverse element: a solution x of the equation ax≡1(mod n), which is called the inverse of a modulo m.

An important application of inverse element is to find the modulus of division:

For example, (a/b)%m=?

Suppose the inverse element of b is k, then (a/b)%m=((a/b)%m)((bk)%m)=(a/b*bk)%m=(ak)%m

Therefore, finding the value of (a/b)%m is equivalent to finding the inverse element of b

 

Several methods to find the inverse element:

1. Extended Euclidean algorithm

Solving the equation ax≡1(mod m) is equivalent to solving ax+my=1 (ax-1 is an integer multiple of m, let y be a multiple, then ax-1=my, that is, ax+my=1, y can be negative );

The solvable condition is: gcd(a,m)=1, that is, a and m are relatively prime.

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

int mod_inverse(int a,int m) {
	int x,y;
	extend_gcd(a,m,x,y);
	return(m+x%m)%m;	//x可能是负数,需要处理 
}

2. Fermat's little theorem

Let m be a prime number and a%m≠0, then a^(m−1)≡1(mod m).

Then a*a^(m-2)≡1(mod m), then its inverse is a^(m-2). The inverse element can be solved with fast power

typedef long long ll;
ll quick_pow(ll b, ll n) {
    ll ans = 1, po = b;
    while(n) {
        if(n & 1)   ans = (ans * po) % mod;
        po = (po * po) % mod;
        n >>= 1;
    }
    return ans;
}

3. Solve the inverse element linearly

Under the modulus prime number p, find the 1~n inverse element , n<p. All inverses can be found in O(n).

假设 p=k*i+j, (1<i<p,j<i)

We can know that p=k∗i+j≡0(mod p)

Multiply both sides by (ij)^(-1) to get i^(-1)+k*j^(-1)=0

Then the change can be i^(-1)=-k*j^(-1)  (1/i is the inverse element of i, and 1/j is the inverse element of j)

And it is known that 1^(-1) 1(mod p)

So we can get the recurrence a[i]=-(p/i)*a[p%i]

a[1]=1

 

In addition: All inverse element values ​​of 1->p modulo p correspond to all numbers in 1->p , for example, p=7, then the inverse element corresponding to 1->6 is 1 4 5 2 3 6

void inverse(int n, int p) {
    a[1] = 1;
    for (int i=2; i<=n; ++i) {
        a[i] = (ll) (p - p / i) * a[p%i] % p;
    }
}

 

 

Reference link: https://blog.csdn.net/guhaiteng/article/details/52123385

                   https://www.cnblogs.com/lifehappy/p/12763635.html

 

Guess you like

Origin blog.csdn.net/qq_44132777/article/details/107347619