快速幂和慢速乘

快速幂

前置知识

  • 位运算
  • 指数幂的运算

对这两个不熟悉的要到网上去看看或查找其他便民设施

快速幂的简介及代码实现

快速幂就是用来快速计算\(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这种整数的乘法,很简单,跟快速幂差不多的思想,把乘改加就行了。

猜你喜欢

转载自www.cnblogs.com/wyc06/p/12293528.html
今日推荐