例1 a^b
很明显,这就是常用的快速幂,但是之前都是背下快速幂的模板,今天算是弄明白了
例:求3^7
7的二进制位111
如图:
通过判断二进制的最低位是否为1,来决定是否将当前的结果累积到答案中
但是要注意p为1的情况 之前的模板里一直没考虑这个…
直接上代码:
#include <iostream>
using namespace std;
int main()
{
long long a,b,p;
cin>>a>>b>>p;
long long res=1%p;//如果p为1 结果永远为0
while(b)//从b的最低位开始考虑
{
if(b&1)//如果最低位为1
{
res=(res*a)%p;//把当前的结果累积到答案中
}
a=(a*a)%p;//将a进行倍增 准备进行下一次的累积 这里的倍增一定是2的某某次方
b>>=1;//把最低位去掉
}
cout<<res<<endl;
return 0;
}
例2 64位整数乘法
这道题与上一道题的区别在于,这道题是利用加法进行倍增,而上一题是利用乘法进行倍增
例:ab=37
#include <iostream>
using namespace std;
typedef long long ll;
ll a,b,p;
int main()
{
cin>>a>>b>>p;
ll res=0;//由于是加法 res要初始化成0 或者将res放在全局变量
while(b)//从b的最低位开始考虑
{
if(b&1)//如果最低位为1
{
res=(res+a)%p;//将当前的结果累加到答案中
}
b>>=1;//去掉最低位
a=(2*a)%p;//将a进行倍增 准备进行下一次的累加 这里的倍增一定是2的某某倍数
}
cout<<res<<endl;
return 0;
}
这章还有一道二进制优化状压dp的题,没看懂,等之后再补上!
刚学算法不久,感觉还没入门,希望大佬们能指出不当的地方,我将感激不尽!