快速幂的思想在于快速求解高幂指数的幂运算 复杂度为O(log2n) 与朴素运算相比有很大的改进
接下来给出代码 其中有详解
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL pow1(int a,int b)///最常规的方法
{
LL ans=1;
while(b--)
ans*=a;
return ans;
}
/**
将幂指数转化为2进制
b=bn*2^n+b(n-1)*2^(n-1)+…+b1*2+b0
a^b=a^(bn*2^n+b(n-1)*2^(n-1)+…+b1*2+b0)
a^b=a^(bn*2^n)*a^(b(n-1)*2^(n-1))*…*a^(b1*2)*a
即若b转化成2进制后 若当前位为0则该项为1
**/
LL pow2(int a,int b)///二分快速幂
{
LL ans=1,base=a;
while(b!=0)
{
if(b%2)
ans*=base;
base*=base;
b/=2;
}
return ans;
}
LL pow3(int a,int b)///同pow2(位运算)
{
LL ans=1,base=a;
while(b!=0)
{
if(b&1)///相当于 b%2==1
ans*=base;
base*=base;
b>>=1;///相当于 b/=2
}
return ans;
}
int main()
{
int a,b;
while(cin>>a>>b)
{
cout<<pow1(a,b)<<endl;
cout<<pow2(a,b)<<endl;
cout<<pow3(a,b)<<endl;
}
return 0;
}
有了快速幂的基础求解(a^b)%c 就变得很简单了
/**
同样是二分的思想 位运算
a*b%c=(a%c)*(b%c)%c
**/
int quickmod(int a,int b,int c)
{
LL ans=1,base=a;
while(b!=0)
{
if(b&1)
ans=(ans*base)%c; /// 该处的base=a^(2^i)%c 乘到ans上
b>>=1; ///计算下一位
base=base*base%c;///防止超 对c取余
}
return ans;
}