目录
1--大数取余
给定大数 a^n,返回其对 p 取余的结果,即 a^n % n;
2--循环取余
主要原理:
基于 (a * b) % p = [(a % p) * (b % p)] % p;则 a^n % p = [(a % p) * a^(n-1) % p] % p,用一个变量 res 记录当前的 a^(n-1) % p,循环计算和更新 res;(类似于动态规划,递推过去);
循环遍历 n,复杂度为 O(n);
// 循环取余 计算 a^n % p
long long pow(long long a, long long n, long long p){
long long res = 1;
a = a % p;
for(int i = 1; i <= n ; i++){
res = (res * a) % p;
}
return res;
}
3--快速幂取余
主要原理:原理讲解参考
a^n%p = a^(2*(n/2))) = ((a^2)%p)^(n/2)%p;
n为偶数时,a^n%p = (a^2 % p)^(n//2)%p;
n为奇数时,a^n%p = [(a%p)(a^(n-1)%p)]%p; 即将 n-1 转化为偶数;
速记:
指数 n 为偶数时,将底数a与自身相乘,将指数 n 整除 2;
指数 n 为奇数时(用 n % 2 == 1 为 true 判断),先将一个 a 提出来与当前结果相乘,再将底数与自身相乘,最后将指数 n 整除 2;
不断循环 n,直到 n == 0 结束,复杂度为 O(log_n);
// 快速幂取余 计算 a^n % p
long long fast_pow(long long a, long long n, long long p){
long long res = 1;
a = a % p;
while(n){
// 奇数
if(n%2 == 1){
res = (res * a) % p;
}
a = a * a;
n = n / 2;
}
return res;
}
4--代码实例
class Solution(object):
def cuttingRope(self, n):
if n <= 3:
return n - 1
num = n / 3
mod = n % 3
p = 1000000007
if mod == 0:
return self.pow(3, num, p)
elif mod == 1:
return self.pow(3, num-1, p) * 4 % p
else:
return self.pow(3, num, p) * 2 % p
def pow(self, a, n, p):
a = a % p
res = 1
for i in range(n):
res = (a * res) % p
return res
def fast_pow(self, a, n, p):
a = a % p
res = 1
while(n):
if(n%2 == 1):
res = res * a % p
a = a*a
n = n /2
return res