版权声明:转载请保留原地址 https://blog.csdn.net/u012972031/article/details/82719222
缘起:因为要学习斐波那契数列的快速算法,所以学一下快速幂。网上的答案多半比较琐碎,看了半天看不出个所以然来,最终写了一下代码并心算了一下,才明白。
先贴一下代码吧。
#include<cstdio>
#include<iostream>
using namespace std;
int poww(int,int);
int main(){
cout<<poww(2,8);
}
int poww(int a,int b){
int ans=1,base=a;
while(b!=0){
if(b&1){//如果是奇数
ans*=base;//向结果赋值
}
base*=base;//基础相乘
b=b/2;
}
return ans;
}
我在学习过程中认为比较难懂的地方有如下几个:
- 位运算b&1的意思。这里我理解为了判断奇偶数。如果b&1=1,则b为奇数。如果b&1=0,则b是偶数。
- 为什么快速幂速度快。大概是因为乘数的次数变少了。
- b>>=1的意思。其实就是b=b/2。
- 如何理解并记住。我是直接写了几遍就背过了。
接下来做了一下luogu的快速幂的题,拿了44分,看了一下题解发现原因是没有mod。不仅要在输出mod,还要在快速幂的过程中mod。
zyc大佬的指点
模运算的性质:(a(+|-|×)b)%c=(a%c)(+|-|×)(b%c) (除法不满足这个性质)
也就是说:(a*b*c*...) mod d=(a mod d)*(b mod d)*(c mod d)*...
#include<cstdio>
#include<iostream>
using namespace std;
long poww(long,long,long);
int main(){
long b,p,k;
cin>>b>>p>>k;
long ans=poww(b,p,k);
cout<<b<<"^"<<p<<" mod "<<k<<"="<<ans%k<<endl;
return 0;
}
long poww(long a,long b,long k){
long ans=1,base=a;
while(b!=0){
if(b&1){//b为奇数
ans=ans*base%k;
}
base=base*base%k;
b=b/2;
}
return ans;
}