欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > P1226 快速幂

P1226 快速幂

2025/9/14 14:58:06 来源:https://blog.csdn.net/2302_80118884/article/details/144226387  浏览:    关键词:P1226 快速幂

【STUACM-算法入门-快速幂】https://www.bilibili.com/video/BV1Hi4y1L7qB?p=2&vd_source=e583d26dc0028b3e6ea220aadf5bc7fe

想先把a的b次方算出来再对p取模是不可能的,因为肯定超出long long 范围。

需要知道:(x*y)mod p = (x mod p)*(y mod p) mod p

这样考虑:

long long sum  = 1;

for(int i = 0;i< b;i ++)

sum = (sum * a) % p;这样会超时,因为b可能很大,需要引入快速幂算法

快速幂的方法很多,这里介绍一种

举一个具体的例子,比如计算2的15次方mod9

15 的二进制是 1111 

 2^15 = 2^(8)*2^(4)*2^(2)*2(1) = 2^(2^3) * 2^(2^2)*2(2^1)*2(2^0),像这样把

 

因为b的二进制位数最多31位,所以只需要算出a^(2^1)mod q——a^(2^32)mod q次方即可(这里mod q是由于之间保存a的高次幂会超出范围,根据模运算的性质保存取模之后的数)

我们不妨建立一个数组num,num[i] 保存着 a^(2^i) mod p的值 ,然后看看b的二进制有哪些位是1,依次判断最后计算时要取num数组中的哪些项。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num[34];//num[i] recorded a^(2^i) mod p的值 
void func(ll a,ll p){//打表ll sum = 1;num[0] = a % p;for(int i = 1;i < 32;i ++){num[i] = (num[i - 1] * num[i - 1]) % p;} 
}
ll calculate(ll b,ll p){ll ans = 1;ll temp,i = 0;while(b){temp = b & 1;if(temp){ans = (ans * num[i]) % p;}b = b >> 1;i ++;}return ans;
}
int main(){ll a,b,p;cin >> a >> b >> p;func(a,p);printf("%lld^%lld mod %lld=%lld",a,b,p,calculate(b,p));return 0;
}
//2^15 15 = b1111 2^15 = 2^(8)*2^(4)*2^(2)*2(1)
// = 2^(2^3) * 2^(2^2)*2(2^1)*2(2^0)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com