以该题为例
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; }