牛客 模板 快速幂

#include<iostream>
using namespace std;
typedef long long ll;
ll qui(ll a,ll b,ll p)
{
    ll res=1;
    a%=p;//提前对a取余防止a过大
    while(b)
    {
        if(b&1)//b%2==1
        {
            res=res*a%p;
        }
        a=a*a%p;
        b>>=1;//右移一位,相当于b/=2
    }
    return res%p;
}
int main()
{
    ll t,a,b,p;
    cin>>t;
    while(t--)
    {
        cin>>a>>b>>p;
        cout<<qui(a,b,p)<<'\n';
    }
    return 0;
}

这段代码实现了一个快速幂算法(也称为模幂运算),用于高效地计算 a^bmodp 的值,其中 a、b 和 p 是非负整数,且 p 通常是一个大质数(在密码学和数论中很常见)。快速幂算法通过将指数 b 表示为二进制形式并迭代计算,显著减少了乘法操作的次数,从而提高了效率。

函数 qui(ll a, ll b, ll p)
  • 参数:接受三个参数 a(底数)、b(指数)、p(模数)。
  • 返回值:返回 abmodp 的结果。
  • 实现步骤
    1. 初始化结果res = 1,因为任何数的0次方都是1(模意义下也成立)。
    2. 对底数取模a %= p,防止在后续计算中 a 变得过大。
    3. 迭代处理指数:通过循环,将指数 b 的每一位(二进制)逐一处理。
      • 如果 b 的当前位是1(即 b & 1),则将 res 乘以 a 并取模 p
      • 然后,无论 b 的当前位是0还是1,都将 a 自乘(a = a * a % p)并准备处理 b 的下一位。注意,这里 a 的自乘是在取模 p 之后进行的,保证了 a 不会过大。
      • 通过 b >>= 1(右移一位,相当于 b /= 2,但更高效),处理 b 的下一位。
    4. 返回结果:由于 res 在计算过程中已经对 p 取了模,所以最终的 res 就是 a^bmodp 的结果。
main 函数
  • 输入:首先读取一个整数 t,表示测试用例的数量。然后,对于每个测试用例,读取三个整数 ab 和 p
  • 处理:对于每个测试用例,调用 qui 函数计算 abmodp 的值,并输出结果。
  • 输出:每个测试用例的结果占一行。

快速幂知识总结

快速幂算法是一种高效的算法,用于计算形如 abmodp 的表达式。它通过以下方式减少乘法操作的次数:

  • 二进制表示:将指数 b 表示为二进制形式,例如 b=(bk​…b2​b1​b0​)2​,其中 bi​ 是0或1。
  • 迭代计算:从 b 的最低位开始,逐位处理。如果当前位是1,则将当前结果乘以底数的某个幂次(该幂次是2的当前位索引次幂,但已经在迭代过程中计算好了),并取模。无论当前位是0还是1,都更新底数的幂次(将其平方并取模),然后处理下一位。
  • 优化:在迭代过程中,通过取模操作防止中间结果过大,从而避免了整数溢出的问题。

快速幂算法的时间复杂度为 O(logb),远优于朴素的 O(b) 方法,特别是当 b 非常大时,效率提升尤为显著

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值