“算法精粹:快速幂技术及其在逆元求解中的应用“

快速幂

快速幂:快速求ab % p的问题,时间复杂度:O(logb),若对于n组数据,那么时间复杂度为O(n∗logb)

给定 𝑛 组 𝑎𝑖,𝑏𝑖,𝑝𝑖,对于每组数据,求出𝑎𝑖𝑏𝑖mod𝑝𝑖 的值。

输入格式

第一行包含整数 𝑛。

接下来 𝑛 行,每行包含三个整数 𝑎𝑖,𝑏𝑖,𝑝𝑖。

输出格式

对于每组数据,输出一个结果,表示 𝑎𝑖𝑏𝑖mod𝑝𝑖 的值。

每个结果占一行。

数据范围

1≤𝑛≤100000,
1≤𝑎𝑖,𝑏𝑖,𝑝𝑖≤2×109

输入样例:
2
3 2 5
4 3 9
输出样例:
4
1

一.暴力解法 O(n∗b)会TLE

基本思路:对于n组数据,分别循环b次求出ab mod p

#include<iostream>
using namespace std;
int main()
{
   
   
    int n;
    cin>>n;
    while(n--)
    {
   
   
        int a,b,p;
        long long res=1;
        cin>>a>>b>>p;
        while(b--)
            res = res * a %p;
        cout<<res<<endl;
    }
}

二.快速幂解法 O(n∗logb)

基本思路:


注意:

  • b&1就是判断b的二进制表示中第0位上的数是否为1,若为1,b&1=true,反之b&1=false
  • b&1也可以用来判断奇数和偶数,b&1=true时为奇数,反之b&1=false时为偶数

快速幂之迭代版 O(n∗logb)

#include<iostream>
using namespace std;
long long qmi(long long a,int b,int p)
{
   
   
    long long res=1;
    while(b)//对b进行二进制化,从低位到高位
    {
   
   
        //如果b的二进制表示的第0位为1,则乘上当前的a
        if(b&1) res = res *a %p;
        //b右移一位
        b>>=1;
        //更新a,a依次为a^{2^0},a^{2^1},a^{2^2},....,a^{2^logb}
        a=a*a%p;
    }
    return res;
}
int main()
{
   
   
    int n;
    cin>>n;
    while(n--