Primera observación: cada vez que multiplicas, debes reducir el mod c. Esto evitará que sus números sean demasiado grandes (en términos de número de dígitos). Ese algoritmo se vería así:
def exp_mod(a, b, c): ans = 1 for i from 1 to b: ans = (ans * a) % c return ans
Esto requiere un total de b multiplicaciones. Sin embargo, podemos hacerlo mejor. Al escribir b en binario (es decir, como la suma de las potencias de 2), podemos escribir [matemáticas] a ^ b [/ matemáticas] como producto de alguna potencia de 2 potencias de a. Por ejemplo
[matemáticas] a ^ {91} = a ^ {64} \ cdot a ^ {32} \ cdot a ^ 8 \ cdot a ^ 2 \ cdot a [/ math]
En general, podemos escribir [matemáticas] a ^ b [/ matemáticas] como [matemáticas] O (\ log b) [/ matemáticas] multiplicaciones como esta. Y también podemos calcular las potencias de 2 potencias en multiplicaciones [matemáticas] O (\ log b) [matemáticas] usando el cuadrado repetido:
- ¿Cómo podemos encontrar eficientemente el número (conteo) de los números de Fibonacci entre dos enteros positivos dados?
- ¿Cuáles son los errores de la interpolación bilineal y la interpolación de spline bicúbica?
- ¿Por qué el número 1 tiene propiedades diferentes de otros números? ¿Es porque tiene una dimensión única?
- ¿Cómo explicarías un algoritmo de tamiz cuadrático a un estudiante de secundaria?
- Cómo resolver un problema de hacer cambios tomando como máximo una moneda de un tipo usando programación dinámica
[matemáticas] a ^ 2 = a \ cdot a [/ matemáticas]
[matemáticas] a ^ 4 = a ^ 2 \ cdot a ^ 2 [/ matemáticas]
[matemáticas] a ^ 8 = a ^ 4 \ cdot a ^ 4 [/ matemáticas]
Nuevamente, para cada multiplicación, deberíamos hacer una operación de módulo para evitar que los números sean demasiado altos. Usando la cuadratura repetida terminamos con [math] O (\ log b) [/ math] multiplicación y operaciones de módulo.