Task: rewrite the given python program to improve its speed of execution.

Original program (CPU time: 433 ms):
n = int(eval(input()))
a = list(map(int, input().split()))
D = {i: [0] for i in range(1, n+1)}
for i in range(n+1):
  D[a[i]][0] += 1
  D[a[i]].append(i)
pl, pr = 0, 0
for i in D:
  if D[i][0] == 2:
    pl = D[i][1]
    pr = D[i][2]
    break
L = pl
M = pr - pl - 1
N = n - pr
mod = int(1e9) + 7 # <-- input modulo
maxf = n+11          # <-- input factional limitation

def make_fact(n, k):
    tmp = n
    perm = [i for i in range(k)]
    L = [0 for _ in range(k)]
    for i in range(k):
        L[i] = tmp % (i + 1)
        tmp //= i + 1
    LL = [0 for _ in range(k)]
    for i in range(k):
        LL[i] = perm[L[-i-1]]
        for j in range(L[-i-1]+1, k):
            perm[j-1] = perm[j]
    return LL

def doubling(n, m, modulo=mod):
    y = 1
    base = n
    tmp = m
    while tmp != 0:
        if tmp % 2 == 1:
            y *= base
            if modulo > 0:
                y %= modulo
        base *= base
        if modulo > 0:
            base %= modulo
        tmp //= 2
    return y

def inved(a, modulo=mod):
    x, y, u, v, k, l = 1, 0, 0, 1, a, modulo
    while l != 0:
        x, y, u, v = u, v, x - u * (k // l), y - v * (k // l)
        k, l = l, k % l
    return x % modulo

fact = [1 for _ in range(maxf+1)]
invf = [1 for _ in range(maxf+1)]

for i in range(maxf):
    fact[i+1] = (fact[i] * (i+1)) % mod
invf[-1] = inved(fact[-1])
for i in range(maxf, 0, -1):
    invf[i-1] = (invf[i] * i) % mod

for i in range(1, n+2):
  S = fact[n]*invf[i-1]*invf[n-i+1]%mod
  if i <= n-1:
    S += fact[n-1]*invf[i]*invf[n-1-i]%mod
    S %= mod
  if i <= n-M:
    S -= fact[n-1-M]*invf[i-1]*invf[n-M-i]%mod
    S %= mod
  if i <= n:
    S += fact[n-1]*invf[i-1]*invf[n-i]%mod
    S %= mod
  print(S)

Optimized program (CPU time: 334 ms):
n = int(eval(input()))
a = list(map(int, input().split()))
D = {i: [0] for i in range(1, n+1)}
for i in range(n+1):
  D[a[i]][0] += 1
  D[a[i]].append(i)
pl, pr = 0, 0
for i in D:
  if D[i][0] == 2:
    pl = D[i][1]
    pr = D[i][2]
    break
L = pl
M = pr - pl - 1
N = n - pr
mod = int(1e9) + 7 # <-- input modulo
maxf = n+11          # <-- input factional limitation

def make_fact(n, k):
    tmp = n
    perm = [i for i in range(k)]
    L = [0 for _ in range(k)]
    for i in range(k):
        L[i] = tmp % (i + 1)
        tmp //= i + 1
    LL = [0 for _ in range(k)]
    for i in range(k):
        LL[i] = perm[L[-i-1]]
        for j in range(L[-i-1]+1, k):
            perm[j-1] = perm[j]
    return LL

def doubling(n, m, modulo=mod):
    y = 1
    base = n
    tmp = m
    while tmp != 0:
        if tmp % 2 == 1:
            y *= base
            if modulo > 0:
                y %= modulo
        base *= base
        if modulo > 0:
            base %= modulo
        tmp //= 2
    return y

def inved(a, modulo=mod):
    x, y, u, v, k, l = 1, 0, 0, 1, a, modulo
    while l != 0:
        x, y, u, v = u, v, x - u * (k // l), y - v * (k // l)
        k, l = l, k % l
    return x % modulo

fact = [1 for _ in range(maxf+1)]
invf = [1 for _ in range(maxf+1)]

for i in range(maxf):
    fact[i+1] = (fact[i] * (i+1)) % mod
invf[-1] = inved(fact[-1])
for i in range(maxf, 0, -1):
    invf[i-1] = (invf[i] * i) % mod

for i in range(1, n+2):
  S = fact[n+1]*invf[i]*invf[n-i+1]%mod
  if i <= n-M:
    S -= fact[n-1-M]*invf[i-1]*invf[n-M-i]%mod
    S %= mod
  print(S)