快速幂&快速幂求逆元

快速幂

c++

快速幂

/*
 * 快速幂
 *
 * 用途:
 *      用于快速求解  a ^ b % p 的数值
 *      a ^ b % p = (a % p) ^ b % p
 *      我们可以将 b 按照二进制的形式拆分开
 *      = {(a % p) ^ 1 if b0 == 1 else 1} % p * 
 *        {(a % p) ^ 2 if b1 == 1 else 1} % p * 
 *        {(a % p) ^ 4 if b2 == 1 else 1} % p * 
 *        ***
 *        {(a % p) ^ (2 ^ k)) if bk == 1 else 1} % p 
 *      k 为 b 的二进制位数,这样的话,可以看出,复杂度为 log b
 *
 */
#include <iostream>
#include <cstdio>

using namespace std;

typedef long long LL;

int qmi(LL a, LL b, LL p) {
    LL res = 1;
    while (b) {
        if (b & 1) {
            res = res * a % p;
        }
        a = a * a % p;
        b >>= 1;
    }
    return res;
}

int main()
{
    int n;
    LL a, b, p;
    scanf("%d", &n);
    while (n -- ) {
        scanf("%lld%lld%lld", &a, &b, &p);
        printf("%lld\n", qmi(a, b, p));
    }


    return 0;
}

快速幂求逆元

C++

快速幂求逆元

/*
 * 快速幂求逆元
 *
 * 逆元定义:
 *      乘法逆元,是指数学领域群G中任意一个元素a,都在G中有唯一的逆元a‘,具有性质a×a'=a'×a=e,其中e为该群的单位元。
 *      (注意是群中的任意一个元素都存在逆元,这里证明过于复杂) -> 这个群和环的定义,需要看数学思维方式与创新了
 *
 * EG:
 *      4关于模7的乘法逆元为多少?
 *      假设是 x ,那么
 *          4x = 1 (mod 7)
 *          转化为 4x + 7y = 1,x 的解
 *
 * 费马小定理(Fermat's little theorem):
 *      如果p是一个质数,而整数a不是p的倍数,则有a ^(p-1)≡ 1(mod p)。
 *
 *      i->因此 a 的逆元是 a ^ (p - 2)
 *
 *      忘记的话,可以写一下模 7 的群,自己试一试
 *
 */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>

using namespace std;

typedef long long LL;

void solve(LL a, LL p) {
    if (a % p == 0) {
        printf("impossible\n");
    } else {
        int b = p - 2;
        LL res = 1;
        while (b) {
            if (b & 1) {
                res = res * a % p;
            }
            b >>= 1;
            a = a * a % p;
        }
        printf("%lld\n", res);
    }
}

int main()
{
    int n;
    scanf("%d", &n);

    LL a, p;
    while (n -- ) {
        scanf("%lld%lld", &a, &p);
        solve(a, p);
    }

    return 0;
}


posted @ 2022-06-29 19:36  lucky_light  阅读(117)  评论(0编辑  收藏  举报