কম্পিউটার টিউটোরিয়াল

পাইথনে পারমুটেশন থেকে সম্ভাব্য সঠিক পারমুটেশন들의 সূচকের যোগফল বের করার প্রোগ্রাম

একটি সংখ্যা n দেওয়া আছে। ১ থেকে n পর্যন্ত পজিটিভ ইন্টিজার দিয়ে সব সম্ভাব্য পারমুটেশন তৈরি করুন এবং লেক্সিকোগ্রাফিক্যালি সাজান। এখানে একটি 'স্পেশাল পারমুটেশন' দেওয়া আছে যেখানে কিছু মান ভুলে গিয়ে 0 দিয়ে রিপ্লেস করা হয়েছে। আমাদের সঠিক পারমুটেশনগুলো খুঁজে বের করে তাদের সূচকের যোগফল বের করতে হবে।

উদাহরণ

input_arr = [0, 2, 0], n = 3 → আউটপুট: 7

সম্ভাব্য পারমুটেশন: [1, 2, 3] (সূচক ২) এবং [3, 2, 1] (সূচক ৫) → যোগফল = ৭

এলগরিদম

  1. modulo := 10⁹+7, i2 := 2^(modulo-2) mod modulo
  2. ফ্যাক্টোরিয়াল অ্যারের fact তৈরি করুন।
  3. cnt := input_arr-এ 0-এর সংখ্যা
  4. যদি cnt == 0:
    • বাইনারি সার্চ (bisect) ব্যবহার করে পারমুটেশন র‍্যাঙ্ক বের করুন।
  5. অন্যথায়:
    • মিসিং সংখ্যাগুলো চিহ্নিত করুন।
    • প্রিফিক্স সাম এবং মডুলার এরিথম্যাটিক ব্যবহার করে রেজাল্ট ক্যালকুলেট করুন।
  6. (res + fact[cnt]) % modulo রিটার্ন করুন।

পাইথন কোড

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 * ik + 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

print(solve([0, 2, 0], 3))  # আউটপুট: 7

ইনপুট / আউটপুট

[0, 2, 0], 3
7
  1. পাইথনে গ্রাফ সবাই দ্বারা ট্রাভার্সেবল কিনা চেক করার প্রোগ্রাম

  2. গোডাউনে কতগুলো বক্স রাখা যায় তা বের করার পাইথন প্রোগ্রাম

  3. পাইথন প্রোগ্রামে অ্যারের যোগফল বের করা

  4. পাইথনে অ্যারের যোগফল বের করা