P1226 【模板】快速幂||取余运算
输入b,p,k的值,求b^p mod k的值。其中b,p,k*k为长整型数。题目描述
输入格式:输入输出格式
三个整数b,p,k.
输出格式:
输出“b^p mod k=s”
s为运算结果
输入输出样例
输入样例#1:
2 10 9
输出样例#1:
2^10 mod 9=7
TIPS:原理:将某个数字多次自乘化为它的若干次幂的少次相乘,从而减少计算量,提高效率。转化的方法如下:将指数写成二进制之后,从右到左,如果为0则跳过,如果为1则乘底数的2的(位数-1)次幂,如:100^10D = 100^1010B= 100^10B * 100 ^ 1000B=100^2D * 100^8D。另外计算数字较大,所以要取余运算。取余运算有几个重要的性质需要使用:
(括号的余等于括号中每项分别取余再取余)
-
(a + b) % p = (a % p + b % p) % p (1)
-
(a - b) % p = (a % p - b % p) % p (2)
-
(a * b) % p = (a % p * b % p) % p (3)*使用在快速幂中
-
a ^ b % p = ((a % p)^b) % p (4)
-
结合律:((a+b) % p + c) % p = (a + (b+c) % p) % p (5)
((a*b) % p * c)% p = (a * (b*c) % p) % p (6)
-
交换律:(a + b) % p = (b+a) % p (7)
(a * b) % p = (b * a) % p (8)
-
分配律:(a+b) % p = ( a % p + b % p ) % p (9)((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (10)
重要定理
-
若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);(11)
-
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);(12)
-
若a≡b (% p),c≡d (% p),则 (a + c) ≡ (b + d) (%p),(a - c) ≡ (b - d) (%p),(a * c) ≡ (b * d) (%p),(a / c) ≡ (b / d) (%p); (13)
#include<cstdio>
#include<iostream>
int main(void){
long base,b,p,pow,k,s = 1;
scanf("%ld %ld %ld", &base, &pow, &k);
b = base;
p = pow;
while(p){
if(p&1){
s = s * b % k;
}
b = b * b % k;
p = p >> 1;
}
printf("%ld^%ld mod %ld=%ld\n", base, pow, k, s % k);
return 0;
}