Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find number of ways we can select sequence from Ajob Sequence in Python
Suppose there is a strange language called Ajob language with infinite letters. We know n words in this language where the first word is one character long, second is two characters long, and so on. All letters in a word are unique.
We need to select any word and form a subsequence from it where the subsequence length should be k less than the original word length. If a word length is L, then subsequence length should be (L - k). Words with length smaller than k cannot be chosen.
Two subsequences are different if they have different lengths or contain different characters at the same position. We need to find the result modulo p, where p is a prime number.
Example
If n = 6, k = 5, p = 11, then the output will be 7.
Algorithm Steps
To solve this problem, we will follow these steps ?
- Create an empty dictionary
memofor memoization - Increment both n and k by 1
- Calculate factorial array modulo p
- Calculate inverse factorial array using modular multiplicative inverse
- Use Lucas theorem to compute combinations modulo prime p
- Return the final result
Implementation
Let us see the implementation to understand better ?
memo = {}
def solve(n, k, p):
n += 1
k += 1
# Calculate factorial array
fact = [1]
for i in range(1, p):
fact.append(fact[-1] * i % p)
# Check if inverse factorials are already computed
if p in memo:
inv_fact = memo[p]
else:
# Calculate modular multiplicative inverses
inv = [0, 1]
for i in range(2, p):
inv.append(p - p // i * inv[p % i] % p)
# Calculate inverse factorial array
inv_fact = [1]
for i in range(1, p):
inv_fact.append(inv_fact[-1] * inv[i] % p)
memo[p] = inv_fact
# Lucas theorem implementation
ret = 1
while n > 0:
n1 = n % p
k1 = k % p
if k1 > n1:
return 0
ret = ret * fact[n1] * inv_fact[k1] * inv_fact[n1 - k1] % p
n //= p
k //= p
return ret
# Test the function
n = 6
k = 5
p = 11
result = solve(n, k, p)
print(f"Number of ways: {result}")
Number of ways: 7
How It Works
This algorithm uses Lucas theorem to compute binomial coefficients modulo a prime. The key steps are:
- Factorial calculation: Precompute factorials modulo p
- Inverse factorial: Calculate modular multiplicative inverses to handle division in modular arithmetic
- Lucas theorem: Recursively compute C(n,k) mod p by breaking down n and k in base p
The algorithm efficiently handles large numbers by working in modular arithmetic throughout the computation.
Conclusion
This solution uses Lucas theorem and modular arithmetic to efficiently calculate the number of ways to select subsequences from the Ajob sequence. The time complexity is O(p + log_p(n)) where p is the prime modulus.
