快速幂取模 | ||
| ||
description | ||
给定A,B,C,计算A^B%C,这里A^B代表A的B次方。
| ||
input | ||
输入数据有多组,每组数据一行,有3个正整数分别为A,B和C,1<=A,B,C<=1000000000
| ||
output | ||
输出A^B%C的值
| ||
sample_input | ||
2 3 5
8 2 10
| ||
sample_output | ||
3
4 |
如果b的值挺小的话 比如100 ,200,1000之类的那么没什么差别,但是b如果好几百亿呢?那么这个时间复杂度为O(n)的算法是显然不行的,所以取余的特性我们就要用二分的方法来求出a^b%m的值 百用百爽
首先 将b以二进制的形式展开为
b=bn*2^n+b(n-1)*2^(n-1)+…+b1*2+b0; 其中bi(0<=i<=n)为0或1。
这个就是二进制表示的意思 你们看懂 看不懂问我 谁要问我这个我会哭的
那么就有等式
a^b=a^(bn*2^n+b(n-1)*2^(n-1)+…+b1*2+b0) 其中bi(0<=i<=n)为0或1
那么把括号打开奇迹就会出现
a^b=a^(bn*2^n)*a^(b(n-1)*2^(n-1))*…*a^(b1*2)*a bi=0的话 那该项就为1
不用处理,只需要考虑bi=1的情况 于是把所有满足bi=1的a^(2^i)按照
上面的算法取余就是结果
上面的算法取余就是结果
代码如下 要利用二分的思想来想
long long quickmod(long long a, long long b, long long m)
{
long long ans=1;
while(b) 用一个循环 从最右向左遍历b的所有二进制位
{
if(b&1) 位运算 按位与操作 相当于b%2==1 也就是判段bi是否为1
{
ans=(ans*a)%m; 乘到结果上 这里的a是 a^(2^i)%m
b--; 把该为变0(这句可有可无)
}
b/=2; 相当于计算接下来左边的二进制位
a=a*a%m; a随着b的移位 不断放大 但是需要对m求余防止数大超范围
}
return ans;
}