Dados tres números a, b y c tales que a, b y c pueden ser como máximo 10 16 . La tarea es calcular (a*b)%c
Una solución simple de hacer ((a % c) * (b % c) ) % c no funcionaría aquí. El problema aquí es que a y b pueden ser grandes, por lo que cuando calculamos (a % c) * (b % c), va más allá del rango que puede contener long long int, por lo que se produce un desbordamiento. Por ejemplo, si a = (10 12 +7), b = (10 13 +5), c = (10 15 +3).
Ahora long long int puede contener hasta 4 x 10 18 (aproximadamente) y a*b es mucho más grande que eso.
En lugar de hacer una multiplicación directa, podemos sumar find a + a + ……….(b veces) y tomar el módulo con c cada vez que agregamos a para que no se produzca un desbordamiento. Pero esto sería ineficiente considerando la restricción en a, b y c. De alguna manera tenemos que calcular (∑ a) % c de manera optimizada.
Podemos usar divide y vencerás para calcularlo. La idea principal es:
- Si b es par entonces a*b = (2*a) * (b/2)
- Si b es impar entonces a*b = a + (2*a)*((b-1)/2)
A continuación se muestra la implementación del algoritmo:
C++
// C++ program to Compute (a*b)%c // such that (a%c) * (b%c) can be // beyond range #include <bits/stdc++.h> using namespace std; typedef long long int ll; // returns (a*b)%c ll mulmod(ll a,ll b,ll c) { // base case if b==0, return 0 if (b==0) return 0; // Divide the problem into 2 parts ll s = mulmod(a, b/2, c); // If b is odd, return // (a+(2*a)*((b-1)/2))%c if (b%2==1) return (a%c+2*(s%c)) % c; // If b is odd, return // ((2*a)*(b/2))%c else return (2*(s%c)) % c; } // Driver code int main() { ll a = 1000000000007, b = 10000000000005; ll c = 1000000000000003; printf("%lldn", mulmod(a, b, c)); return 0; }
Java
// Java program to Compute (a*b)%c // such that (a%c) * (b%c) can be // beyond range // returns (a*b)%c class GFG { static long mulmod(long a, long b, long c) { // base case if b==0, return 0 if (b == 0) { return 0; } // Divide the problem into 2 parts long s = mulmod(a, b / 2, c); // If b is odd, return // (a+(2*a)*((b-1)/2))%c if (b % 2 == 1) { return (a % c + 2 * (s % c)) % c; } // If b is odd, return // ((2*a)*(b/2))%c else { return (2 * (s % c)) % c; } } // Driver code public static void main(String[] args) { long a = 1000000000007L, b = 10000000000005L; long c = 1000000000000003L; System.out.println((mulmod(a, b, c))); } } // This code is contributed by PrinciRaj1992
Python3
# Python3 program of above approach # returns (a*b)%c def mulmod(a, b, c): # base case if b==0, return 0 if(b == 0): return 0 # Divide the problem into 2 parts s = mulmod(a, b // 2, c) # If b is odd, return # (a+(2*a)*((b-1)/2))%c if(b % 2 == 1): return (a % c + 2 * (s % c)) % c # If b is odd, return # ((2*a)*(b/2))%c else: return (2 * (s % c)) % c # Driver code if __name__=='__main__': a = 1000000000007 b = 10000000000005 c = 1000000000000003 print(mulmod(a, b, c)) # This code is contributed by # Sanjit_Prasad
C#
// C# program to Compute (a*b)%c // such that (a%c) * (b%c) can be // beyond range using System; // returns (a*b)%c class GFG { static long mulmod(long a, long b, long c) { // base case if b==0, return 0 if (b == 0) return 0; // Divide the problem into 2 parts long s = mulmod(a, b / 2, c); // If b is odd, return // (a+(2*a)*((b-1)/2))%c if (b % 2 == 1) return (a % c + 2 * (s % c)) % c; // If b is odd, return // ((2*a)*(b/2))%c else return (2 * (s % c)) % c; } // Driver code public static void Main() { long a = 1000000000007, b = 10000000000005; long c = 1000000000000003; Console.WriteLine(mulmod(a, b, c)); } } // This code is contributed by mits
PHP
<?php // PHP program to Compute (a*b)%c // such that (a%c) * (b%c) can be // beyond range // returns (a*b)%c function mulmod($a, $b, $c) { // base case if b==0, return 0 if ($b==0) return 0; // Divide the problem into 2 parts $s = mulmod($a, $b/2, $c); // If b is odd, return // (a+(2*a)*((b-1)/2))%c if ($b % 2 == 1) return ($a % $c + 2 * ($s % $c)) % $c; // If b is odd, return // ((2*a)*(b/2))%c else return (2 * ($s % $c)) % $c; } // Driver Code $a = 1000000000007; $b = 10000000000005; $c = 1000000000000003; echo mulmod($a, $b, $c); // This code is contributed by anuj_67. ?>
Javascript
<script> // javascript program to Compute (a*b)%c // such that (a%c) * (b%c) can be // beyond range // returns (a*b)%c function mulmod(a , b , c) { // base case if b==0, return 0 if (b == 0) { return 0; } // Divide the problem into 2 parts var s = mulmod(a, parseInt(b / 2), c); // If b is odd, return // (a+(2*a)*((b-1)/2))%c if (b % 2 == 1) { return (a % c + 2 * (s % c)) % c; } // If b is odd, return // ((2*a)*(b/2))%c else { return (2 * (s % c)) % c; } } // Driver code var a = 1000000000007, b = 10000000000005; var c = 1000000000000003; document.write((mulmod(a, b, c))); // This code contributed by Princi Singh </script>
Producción :
74970000000035
Vea esto para una ejecución de muestra.
Complejidad de tiempo: O(log b)
Este artículo es una contribución de Madhur Modi . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA