Modulo of factorial divided by factorial
Solution 1:
If a
, b
s and p
are fairly small, prefer @KellyBundy's approach of cancelling factors, or counting prime factors.
Multiplication and modular arithmetic
Given integers m
and n
and some other integer k
:
(m * n) modulo k = ((m modulo k) * (n mod k)) modulo k
This allows a large product to be calculated modulo p
without worrying about overflow, since we can always keep the arguments in the range [0, k)
.
For example to compute the factorial a! modulo k
, in python:
def fact(a, k):
if a == 0:
return 1
else:
return ((a % k) * fact(a - 1, k)) % k
Division and modular arithmetic
If p
is a prime then for any integer n
that is not divisible by p
, we can find an integer which I'll call inv(n)
such that:
(n * inv(n)) modulo p = 1
This number is called the modular inverse of n
. There are various algorithms to find modular inverses, which I won't describe here (but see e.g. here).
Now, given integers n
and m
, and assuming that m / n
is an integer, we can apply the rule:
(m / n) modulo p = (m * inv(n)) modulo p
So provided we can calculate modular inverses, we can convert division to multiplication, and then apply the previous rule.
Solution 2:
Another way, listing the factors 1
to a
, then canceling with all divisors, then multiplying modulo p:
#include <iostream>
#include <vector>
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
int main() {
int a = 60;
std::vector<int> bs = {13, 7, 19};
int p = 10007;
std::vector<int> factors(a);
for (int i=0; i<a; i++)
factors[i] = i + 1;
for (int b : bs) {
while (b > 1) {
int d = b--;
for (int& f : factors) {
int g = gcd(f, d);
f /= g;
d /= g;
}
}
}
int result = 1;
for (int f : factors)
result = result * f % p;
std::cout << result;
}
Prints 5744, same as this Python code:
from math import factorial, prod
a = 60
bs = [13, 7, 19]
p = 10007
num = factorial(a)
den = prod(map(factorial, bs))
print(num // den % p)