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 out the sum of numbers where the correct permutation can occur in python
Given a number n, we need to find all possible permutations of positive integers up to n, sort them lexicographically, and number them from 1 to n!. When some values in a "special permutation" are forgotten (replaced with 0s), we must find all permutations that could match the original and sum their lexicographic positions.
For example, if the special permutation is [0, 2, 0] with n=3, the possible original permutations are [1, 2, 3] (position 2) and [3, 2, 1] (position 5), giving us a sum of 7.
Algorithm Steps
The solution uses factorial number system and modular arithmetic ?
- Calculate factorials for lexicographic position computation
- Count zeros (forgotten positions) in the input array
- Handle two cases: no zeros vs. some zeros present
- Use bisection to maintain sorted order during processing
- Apply modular inverse for division operations
Implementation
import bisect
def solve(input_arr, n):
modulo = 10 ** 9 + 7
i2 = pow(2, modulo-2, modulo)
fact = [1]
for x in range(1, n+1):
fact.append(fact[-1] * x % modulo)
cnt = input_arr.count(0)
if not cnt:
res = 0
seen_list = []
for i, x in enumerate(input_arr, 1):
tmp_val = bisect.bisect(seen_list, x)
res += fact[n-i] * (x - 1 - tmp_val)
res %= modulo
seen_list.insert(tmp_val, x)
return res + 1
else:
ik = pow(cnt, modulo-2, modulo)
miss = [True] * n
for x in input_arr:
if x != 0:
miss[x-1] = False
miss_srtd = []
tmp = 0
for i, x in enumerate(miss, 1):
if x:
miss_srtd.append(i)
tmp += i
pre = [0]
for x in miss:
pre.append(pre[-1] + x)
cnt_cu = 0
s = tmp % modulo * ik % modulo
srtdw = []
res = z = 0
for i, x in enumerate(input_arr, 1):
if x:
l = tmp_val = bisect.bisect(srtdw, x)
l += z * bisect.bisect(miss_srtd, x) % modulo * ik % modulo
p = x - 1 - l
p *= fact[cnt]
p %= modulo
srtdw.insert(tmp_val, x)
cnt_cu += cnt - pre[x]
else:
l = cnt_cu
l *= ik
l += z * i2 % modulo
p = s - 1 - l
p *= fact[cnt]
p %= modulo
z += 1
res += p * fact[n-i] % modulo
res %= modulo
return (res + fact[cnt]) % modulo
# Test with the example
result = solve([0, 2, 0], 3)
print(f"Sum of permutation positions: {result}")
Sum of permutation positions: 7
How It Works
The algorithm uses the factorial number system to compute lexicographic positions efficiently. When zeros are present, it calculates the average contribution of all possible values that could fill those positions, using modular inverse to handle division in modular arithmetic.
Key Components
- Factorial precomputation: Enables O(1) position calculations
- Bisection search: Maintains sorted order for position tracking
- Modular inverse: Handles division operations in modular arithmetic
- Missing values tracking: Identifies which numbers can fill zero positions
Conclusion
This solution efficiently computes the sum of lexicographic positions for all valid permutations using factorial number system and modular arithmetic. The time complexity is O(n²) due to the bisection operations within the main loop.
