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.

Updated on: 2026-03-26T15:22:20+05:30

372 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements