标签:思想 简介 print 前置 sign namespace math 来讲 pow
对这两个不熟悉的要到网上去看看或查找其他便民设施
快速幂就是用来快速计算\(a^b\)的值(废话),朴素算法计算是\(O(n)\)的时间复杂度,快速幂能优化到\(O(logn)\)。
我们用这道例题 题目链接 来讲一下快速幂的实现
以样例中的\(a=2,b=10,p=9\)为例,将指数\(b\)转为二进制\(10=(1010)_2\),根据位值原理,我们可以知道:\(10=1*2^3+0*2^2+1*2^1+0*2^0\)。
所以结果为\(2^{10}=2^8*2^2\)(根据上面的)。所以我们找一个变量\(a\)专门计算这些\(a^{2^n}(n为正整数)\)的值(这里为了方便就直接拿a本身了),当\(b\)中与之对应的值为1时,说明要将\(a\)乘到结果\(res\)里面。
然后注意一下边乘边取余就好了
源代码:
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll; //注意数据范围
ll qpow(ll a, ll n,ll mod)
{
ll res=1%mod;
while(n)
{
if(n&1) //n的二进制末尾是否为1
res=(res*a)%mod; //边乘边取余
n>>=1; //n左移1位
a=(a*a)%mod; //第i次循环,a为原始值乘2^i
}
return res%mod; //最后再取余
}
int main(){
ll b,p,k,i;
cin>>b>>p>>k;
printf("%lld^%lld mod %lld=",b,p,k);
cout<<qpow(b,p,k);
return 0;
}
慢速乘适用于像unsigned long long这种整数的乘法,很简单,跟快速幂差不多的思想,把乘改加就行了。
标签:思想 简介 print 前置 sign namespace math 来讲 pow
原文地址:https://www.cnblogs.com/wyc06/p/12293528.html