AcWing89数论a^b快速幂C++

问题描述

求 a 的 b 次方对 p 取模的值。
输入格式
三个整数 a,b,p ,在同一行用空格隔开。
输出格式
输出一个整数,表示a^b mod p的值。
数据范围
0≤a,b≤109
1≤p≤109
输入样例:
3 2 7
输出样例:
2

这个非常有意

由于是二进制,很自然地想到用位运算这个强大的工具:&和>>
&运算通常用于二进制取位操作,例如一个数 & 1 的结果
就是取二进制的最末位。还可以判断奇偶x&10为偶,
x&1
1为奇。 >>运算比较单纯,二进制去掉最后一位

在实际问题中,题目常常会要求对一个大素数取模,这是因为计算结果可能会非常巨大,但是在这里考察高精度又没有必要。这时我们的快速幂也应当进行取模,此时应当注意,原则是步步取模,如果MOD较大,还应当开long long。

快速幂讲解链接

部分截图

在这里插入图片描述

快速幂拓展链接
在这里插入图片描述

代码&注释

#include <iostream>

using namespace std;
int main() {
    long long a, b, p, res = 1; // a^b % p = ?
    scanf("%ld%ld%ld", &a, &b, &p);
    while(b) {
        // b & 1 用 & 运算符得到 b 二进制的最后一位
        // 最后一位可能是 0 或者 1
        // 如果是 1,答案 res 需要乘以 a 取模 并把结果保存到 res 中
        // 这里用到了 整数转为二进制形式的知识
        // 以b==11为例,b用二进制表示为1011,二进制从右向左算,
        // 但乘出来的顺序是 a^(1 * 2^0)*a^(1 * 2^1)*a^(0 * 2^2)*a^(1 * 2^3),
        // 是从左向右的。我们不断的让a *= a目的即是累乘,因为当 b 右移了一位后
        // 2^x 中的 x 也要增加,而且正好是 a 的平分,即,a = a * a
        // 如果等于 b & 1 == 1 成立,则 b 作为 a 的 次幂,贡献了结果,就要存在res中
        // 所以有 res = res * a 
        // 所有的 % (取模)操作都不会影响最终的取模结果,而且
        // 取模可以防止数据溢出
        if(b & 1) res = res * a % p;
        b >>= 1; // b 右移了一位后,a 也需要更新
        a = a * a % p;
    }
    printf("%ld\n", res % p);
    return 0;
}

网络资源很丰富

你想要的答案要自己搜,自己思考,自己总结一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值