Related Articles

Related Articles

Trick for modular division ( (x1 * x2 …. xn) / b ) mod (m)
  • Difficulty Level : Hard
  • Last Updated : 19 Oct, 2020

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 : 

  1. Simply calculate the product (55*54*53*52*51)= say x,
  2. Divide x by 120 and then take its modulus with 1000000007

Using Modular Multiplicative Inverse : 
The 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. A similar formula for division does not exist. 
i.e (a/b)mod(m) != a(mod(m))/b(mod(m)) 

  1. So we are required to find out the modular multiplicative inverse of b say i and then multiply ‘i’ with a .
  2. 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 the 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. 
 

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement
# the above approach
# To run this code, we need to
# copy modular inverse 
# from below post.
# multiplicative-inverse-under-modulo-m/
 
if __name__ == '__main__':
     
    # naive method-calculating the
    # result in a single line
    naive_answer = (((55555 * 55554 *
                      55553 * 55552 *
                      55551) // 120) %
                      1000000007)
 
    ans = 1
 
    # modular_inverse() is a user
    # defined function that calculates
    # inverse of a number
    i = modular_inverse(120, 10000007)
 
    # it will use extended Eucledian
    # algorithm or Fermat's Little
    # Theorem for calculation.
    # MMI of 120 under divison by
    # 1000000007 will be 808333339
    for i in range(5):
        ans = ((ans *
               (55555 - i)) %
                1000000007)
 
    ans = (ans * i) % 1000000007
    print("Answer using naive method:",
           naive_answer)
    print("Answer using multiplicative" +
          "modular inverse concept:", ans)
 
# This code is contributed by himanshu77

chevron_right


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 an overflow of data resulting in an 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

#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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

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.

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

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.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

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.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?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.
?>

chevron_right


Output : 

Answer using shortcut: 300820513



 

Why did it work? 
This will work only in case when the denominator is a factor of numerator i.e. when a % b = 0 following the rule: 
If b | a, then we can write (a/b) % p as (a % p*b)/b. 
This rule proves useful for small values of b.
Let us consider a = x1*x2*x3…….xn 
We have to find ans = (a/b)%1000000007 

  1. 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
  2. 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). 🙂

competitive-programming-img




My Personal Notes arrow_drop_up
Recommended Articles
Page :