快速幂

以该题为例

a, b的数据规模为10^9,计算a^b就要循环10^9次,这样求幂值当然行不通,于是要引入快速幂的概念

快速幂是基于位运算来的,举个例子,要计算3^7

7的二进制位111

所以原式可等价于3^(001 + 010 + 100)

即3^(001) * 3^(010) * 3^(100)

所以只用判断指数部分二进制格式每一位是否为1,为1就在结果上乘上3的这一位次幂

同时,3的某一位次幂也不用直接算出来,比如

3^(001) = 3^(2^0) = 3^1

3^(010) = 3^(2^1) = 3^2

3^(100) = 3^(2^2) = 3^4

可以看出,某一位的幂值是上一位的平方

#include<iostream>

using namespace std;

typedef long long ll;

int main(){
    ll a, b, p;
    cin >> a >> b >> p;
    ll res = 1 % p; //%p是因为有b的0的情况,这样下面的循环进不去
    while(b){
        if(b&1)
            res = res * a % p;//每次都%p是因为虽然可以降低求幂的次数,但是幂本身仍然是一个大到无法存储的数,因此每一次都%p,这样运算的结果是一样的,但是运算过程中参与计算的数据要小得多
        a = a * a % p;
        b >>= 1;//b右移
    }
    
    cout << res << endl;
    
    return 0;
}

 

 

还有一道类似的题,不过是求乘法

#include<bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;

int main(){
    ull a, b, p;
    cin >> a >> b >> p;
    ull ans = 0;
    
    while(b){
        if(b&1)
            ans = (ans + a) % p;
        a = a * 2 % p;
        b >>= 1;
    }
    cout << ans << endl;
    return 0;
}

 

posted @ 2019-07-26 22:21  zuo_ti_jia  阅读(148)  评论(0编辑  收藏  举报