On the multiplicative inverse in the mold prime significance

Original link (better reading experience)

Reference article www.luogu.org/blog/zyxxs/post-xiao-yi-jiang-tan-qian-tan-sheng-fa-ni-yuan

What is the multiplicative inverse

If the integer \ (b, m \) coprime, and \ (B | A \) , if there exists an integer \ (X \) , so \ (a / b \ equiv a \ ast x (mod \ text {} m ) \) , called \ (X \) is the \ (B \) die \ (m \) multiplicative inverse .

Multiplicative inverse of use

Sometimes, we request \ (A / B \ {text} MOD \ text {P} \) , using simple methods, we can only \ (A \) continuously plus \ (P \) , until it is bb is divisible by far, when \ (a, b, p \ ) have a lot of time, a naturally cool. At this time, we can use the inverse convenient solved.

Multiplicative inverse method of calculating

Entered into the most crucial part of this article, how to find multiplicative inverse?

Fermat's Little Theorem

Fermat's little theorem: when \ (P \) is the number of prime time, $ a ^ {p-1 } \ equiv 1 (mod \ text {} p) $

Then the \ (a ^ {p-1 } \) open to, get a \ (a \ ast a ^ { p-2} \ equiv (mod \ text {} p) \)

Therefore, \ (A-P ^ {2} \) is \ (A \) mode \ (P \) multiplicative inverse in the sense.

Disadvantages: with fast computing power, when \ (p \) when larger, more slowly.

Code:

#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;

ll n, p;

ll ksm(ll a, ll b)
{
    ll ans = 1;
    for (; b; b >>= 1) {
        if (b & 1)
            ans = ans * a % p;
        a = a * a % p;
    }
    return ans;
}

int main()
{
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
    cin >> n >> p;
    for (int i = 1; i <= n; ++i) {
        printf("%lld\n", ksm(i, p - 2));
    }
    return 0;
}

Extended Euclidean Algorithm

Seeking \ (a \ ast x \ equiv 1 (mod \ text {} m) \) Solutions \ (INV (X) \) , equivalent to solving \ (a \ ast x + b \ ast y = 1 \) . Extended Euclidean Algorithm with a determined group of specialized solutions \ (x_0, y_0 \) , then \ (x_0 \) is a solution of the original equation, compared with the general solution for all die \ (m \) and \ ( x_0 \) with the integer remainder by modulo operation of the moving range of the solution to \ (1 ~ p \) to between.

Code:

#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
typedef long long ll;

ll n, p;

void exgcd(ll a, ll b, ll& x, ll& y)
{
    if (b == 0) {
        x = 1, y = 0;
        return;
    }
    exgcd(b, a % b, x, y);
    ll z = x;
    x = y, y = z - y * (a / b);
    return;
}

int main()
{
    cin >> n >> p;
    for (int i = 1; i <= n; ++i) {
        ll x, y;
        exgcd(i, p, x, y);
        x = (x % p + p) % p;
        cout << x << endl;
    }
    return 0;
}

Linear recursion (can find multiple)

This is a magical process ......

Suppose we now require \ (k \) of the multiplicative inverse,

Order \ (a \ ast k + b = p \)

\[b \ast inv(b) \equiv 1 (mod \text{ } p)\]

The \ (b = pa \ ast k \) is substituted, can be obtained

\[(p-ak)\ast inv(b) \equiv 1 (mod \text{ } p)\]

Then

\[p \ast inv(b) - a \ast k \ast inv(b) \equiv 1 (mod \text{ } p)\]

In ((mod \ text {} p ) \) \ in the sense, \ (P \ equiv 0 (MOD \ text {P}) \) , so \ (p \ ast inv (b ) \) can be directly removed

\[-a \ast k \ast inv(b) \equiv 1 (mod \text{ } p)\]

Observation \ (a \ ast k + b = p \) can be found, \ (A = \ lfloor P / K \ rfloor \) , \ (B = P \ MOD K \)

\[-(p/k) \ast inv(p \text{ } mod \text{ } k) \ast k \equiv 1 (mod \text{ } p)\]

which is

\[-(p/k) \ast inv(p \text{ } mod \text{ } k) \equiv inv(k) (mod \text{ } p)\]

In this way, we have a recursive, have to add in the actual code implementations \ (p \) to remove the negative sign, that is,

\[(p-p/k) \ast inv(p \text{ } mod \text{ } k) \equiv inv(k) (mod \text{ } p)\]

Code:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
ll n, p, inv[maxn];

int main()
{
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);
    cin >> n >> p;

    inv[1] = 1;
    for (int i = 2; i <= n; ++i)
        inv[i] = (ll)(p - p / i) * inv[p % i] % p;
    for (int i = 1; i <= n; ++i)
        printf("%lld\n", inv[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/kkkstra/p/11331030.html