Trick for modular division ( (x1 * x2 …. xn) / b ) mod (m)
Given integers x1, x2, x3……xn, b and m, we are supposed to find the result of ((x1*x2….xn)/b)mod(m).
Example 1 : Suppose that we are required to find (55C5)%(1000000007) i.e ((55*54*53*52*51)/120)%1000000007
Naive Method :
- Simply calculate the product (55*54*53*52*51)= say x,
- Divide x by 120 and then take its modulus with 1000000007
Using Modular Multiplicative Inverse :
Above method will work only when x1, x2, x3….xn have small values.
Suppose we are required to find the result where x1, x2, ….xn fall in the range of ~1000000(10^6). So we will have to exploit the rule of modular mathematics which says :
(a*b)mod(m)=(a(mod(m))*b(mod(m)))mod(m)
Note that the above formula is valid for modular multiplication. Similar formula for division does not exist.
i.e (a/b)mod(m) != a(mod(m))/b(mod(m))
- So we are required to find out modular multiplicative inverse of b say i and then multiply ‘i’ with a .
- After this we will have to take the modulus of the result obtained.
i.e ((x1*x2….xn)/b)mod(m)=((x1*x2….xn)*i)mod(m)= ((x1)mod(m) * (x2)mod(m) *…. (xn)mod(m) * (i)mod(m))mod(m)
Note : To find modular multiplicative inverse we can use Extended Eucledian algorithm or Fermat’s Little Theorem.
Example 2 : Let us suppose that we have to find (55555C5)%(1000000007) i.e ((55555*55554*55553*55552*55551)/120)%1000000007.
// To run this code, we need to copy modular inverse // from below post. int main() { // naive method-calculating the result in a single line long int naive_answer = (( long int )(55555 * 55554 * 55553 * 55552 * 55551) / 120) % 1000000007; long int ans = 1; // modular_inverse() is a user defined function // that calculates inverse of a number long int i = modular_inverse(120, 10000007); // it will use extended Eucledian algorithm or // Fermat’s Little Theorem for calculation. // MMI of 120 under division by 1000000007 // will be 808333339 for ( int i = 0; i < 5; i++) ans = (ans * (55555 - i)) % 1000000007; ans = (ans * i) % 1000000007; cout << "Answer using naive method: " << naive_answer << endl; cout << "Answer using multiplicative" << " modular inverse concept: " << ans; return 0; } |
Input : Output :Answer using naive method: -5973653 Answer using multiplicative modular inverse concept: 300820513
It is clear from the above example that the naive method will lead to overflow of data resulting in incorrect answer. Moreover, using modular inverse will give us the correct answer.
Without Using Modular Multiplicative Inverse :
But it is interesting to note that a slight change in code will discard the use of finding modular multiplicative inverse.
C++
#include <iostream> using namespace std; int main() { long int ans = 1; long int mod = ( long int )1000000007 * 120; for ( int i = 0; i < 5; i++) ans = (ans * (55555 - i)) % mod; ans = ans / 120; cout << "Answer using shortcut: " << ans; return 0; } |
Java
class GFG { public static void main(String[] args) { long ans = 1 ; long mod = ( long ) 1000000007 * 120 ; for ( int i = 0 ; i < 5 ; i++) ans = (ans * ( 55555 - i)) % mod; ans = ans / 120 ; System.out.println( "Answer using" + " shortcut: " + ans); } } // This code is contributed by smitha. |
Python3
ans = 1 mod = 1000000007 * 120 for i in range ( 0 , 5 ) : ans = (ans * ( 55555 - i)) % mod ans = int (ans / 120 ) print ( "Answer using shortcut: " , ans) # This code is contributed by Smitha. |
C#
using System; class GFG { public static void Main() { long ans = 1; long mod = ( long )1000000007 * 120; for ( int i = 0; i < 5; i++) ans = (ans * (55555 - i)) % mod; ans = ans / 120; Console.Write( "Answer using " + "shortcut: " + ans); } } // This code is contributed by smitha. |
PHP
<?php $ans = 1; $mod = 1000000007 * 120; for ( $i = 0; $i < 5; $i ++) $ans = ( $ans * (55555 - $i )) % $mod ; $ans = $ans / 120; echo "Answer using shortcut: " , $ans ; // This code is contributed by anuj_67. ?> |
Answer using shortcut: 300820513
Why did it work?
Let us consider a = x1*x2*x3…….xn
We have to find ans = (a/b)%1000000007
- Let result of a%(1000000007*b) be y. To avoid overflow, we use modular multiplicative property. This can be represented as
a = (1000000007*b)q + y where y < (1000000007*b) and q is an integer - Now dividing LHS and RHS by b, we get
y/b = a/b -(1000000007*b)*q/b
= a/b -1000000007*q < 1000000007 (From 1)
Therefore, y/b is equivalent to (a/b)mod(b*1000000007). 🙂
Recommended Posts:
- Modular Division
- Modular Exponentiation (Power in Modular Arithmetic)
- Modular multiplicative inverse from 1 to n
- Modular multiplicative inverse
- Modular exponentiation (Recursive)
- Number of solutions to Modular Equations
- Modular Exponentiation of Complex Numbers
- How to avoid overflow in modular multiplication?
- Find modular node in a linked list
- Using Chinese Remainder Theorem to Combine Modular equations
- Division without using '/' operator
- DFA based division
- Check if it is possible to perform the given Grid Division
- Find the number after successive division
- Maximum value of division of two numbers in an Array
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.