快速幂的用处:
快速幂主要用于指数取模问题,当数据过大时可能超过计算机整数取值范围,此时简单的循环无法满足要求
快速幂原理:
积的取余等于取余的积的取余,式子表达为 (a * b) % c = ((a % c) * (b % c)) % c。
以一道oj题为例
/编写一个程序,当输入两个数a, b时,输出a的b次方(a, b均为整数)!!!最后数字可能可能很大,请输出他除以10的9次方加7的余数;
根据原理理解我们可以简单写出如下程序
#include<stdio.h>
int main()
{
long long int a, b, c, d = 1;
scanf_s("%lld%lld", &a, &b);
if (b == 1)
printf("%lld", a);
else
{
for (c = 1; c <= b; c++)
d = d * a % 1000000007;
printf("%lld", d);
return 0;
}
}
当循环次数较少(只是几千次或更少)时,这种算法当然适用,但是当循环次数超大时,程序运行时间相对较长。
下面看进阶方法
#include <stdio.h>
int main()
{
long long int a, b,mode,sum = 1;
mode = 1000000007;
scanf_s("%lld%lld", &a, &b);
a = a % mode; /* 首先对a取模,取模后不影响结果,根据引理积的取余等于取余的积的取余*/
while (b >0) /*一直循环到b为0*/
{
if (b % 2==1) /*判断次方是否为奇数*/
{
sum=(sum * a)% mode;
}
b /= 2;
a = (a * a)%mode;
}
printf("%lld", sum);
}
假若a=2,b=100;
让2循环100次不如让4循环50次更不如让16循环25次,循环次数不断减少,程序变得更加简单。
那么该程序运行过程首先循环这个过程
直到b为奇数25,
先挑出去一次方单独取模,然后令剩下的偶次数拆2平方取模。
当然也可以把快速幂写成函数,应对多次取模场景
#include<stdio.h>
const long long mod = 1000000007;
long long fastpower(long long base, long long power) {
long long result = 1;
while (power > 0) {
if (power % 2 == 1) {
result = result * base % mod;
}
power = power / 2;
base = (base * base) % mod;
}
return result;
}
int main()
{
long long int a, b, c, d = 1;
scanf_s("%lld%lld", &a, &b);
printf("%lld", fastpower(a, b));
}
希望大家向我提出不足之处,共同进步(^∀^)