【洛谷 P1226】【模板】快速幂 题解(数学+递归+快速幂)

【模板】快速幂

题目描述

给你三个整数 a , b , p a,b,p a,b,p,求 a b   m o d   p a^b \bmod p abmodp

输入格式

输入只有一行三个整数,分别代表 a , b , p a,b,p a,b,p

输出格式

输出一行一个字符串 a^b mod p=s,其中 a , b , p a,b,p a,b,p 分别为题目给定的值, s s s 为运算结果。

样例 #1

样例输入 #1

2 10 9

样例输出 #1

2^10 mod 9=7

提示

样例解释

2 10 = 1024 2^{10} = 1024 210=1024 1024   m o d   9 = 7 1024 \bmod 9 = 7 1024mod9=7

数据规模与约定

对于 100 % 100\% 100% 的数据,保证 0 ≤ a , b < 2 31 0\le a,b < 2^{31} 0a,b<231 a + b > 0 a+b>0 a+b>0 2 ≤ p < 2 31 2 \leq p \lt 2^{31} 2p<231


思路

快速幂算法的主要思想是将指数 b b b进行分解,然后利用乘法的分配性质和取模的性质,将原问题转化为多个子问题的求解,从而大大提高了计算效率。

如果 b b b是偶数,那么 a b m o d    p = ( a b / 2 m o d    p ) 2 m o d    p a^b \mod p = (a^{b/2} \mod p)^2 \mod p abmodp=(ab/2modp)2modp;如果 b b b是奇数,那么 a b m o d    p = ( a b − 1 m o d    p ) × a m o d    p a^b \mod p = (a^{b-1} \mod p) \times a \mod p abmodp=(ab1modp)×amodp。这样,我们就可以将原问题不断分解为规模更小的子问题,直到 b b b等于0,此时 a 0 a^0 a0等于1。

在计算大数的乘方时,结果往往会非常大,导致溢出。为了避免这种情况,在每一步计算中都取模。


AC代码

#include 
#define ll long long
#define AUTHOR "HEX9CF"
using namespace std;

ll qpow(int a, int b, int p) {
	if (!b) {
		return 1;
	}
	if (b % 2 == 1) {
		return (qpow(a, b - 1, p) * a) % p;
	} else {
		ll tmp = qpow(a, b >> 1, p) % p;
		return (tmp * tmp) % p;
	}
	return 0;
}

int main() {
	int a, b, p;
	cin >> a >> b >> p;
	ll ans = qpow(a, b, p);
	printf("%d^%d mod %d=%lld", a, b, p, ans);
	return 0;
}

你可能感兴趣的:(Algorithm,Problems,算法)