算法_次方求模(快速幂)
作者:互联网
求ab % c 的值。其中a, b, c 是整数,且 0 < a,c < 109,0 < b < 1018
暴力算法 O(b)
long long ans = 1; for (long long i = 1; i <= b; i++) { ans *= a; } ans % c;
优化(暴力算法)
根据取模运算的性质,(a * b) % p = [(a % p) (b % p)] % p
所以原式(a · a · a ····· · a)% c ,每乘一次都取模一次,结果不变
long long ans = 1; for (long long i = 1; i <= b; i++) { ans *= a; ans %= c; } ans % c;
但复杂度仍然为O(b)
继续优化(快速幂)
计算310 时,手算为—— 310 = (32)5 = 95 = 9 * 94 = 9 * (81)2 = 9 * (812)1
即:①指数为偶数时:指数除以2,底数平方;②指数为奇数时:ans * 底数 *( 指数除以2,底数平方)
#include <iostream> using namespace std; typedef long long ll; ll fast_power(ll a, ll b, ll p) { ll ans = 1; //初值为1, 因为后续做的是乘法 a %= p; while(b) // 在b不为0时,做b的奇偶性判断 { if (b % 2 == 1) //若为奇数 这里可以改成 (b & 1), 在二进制下,奇数最后一位 1 & 1 = 1;偶数最后一位 0 & 1 = 0 { ans = (ans * a)% p; } a = (a * a) % p; b /= 2; //等价 b >> 1; 二进制中就是右移一位 } return ans; } int main() { ll a, b, p; cin >> a >> b >> p; cout << a << "^" << b << " mod " << p << "=" << fast_power(a, b, p); }
标签:求模,奇数,ll,底数,long,算法,ans,次方 来源: https://www.cnblogs.com/baicang/p/15085133.html