import sys import numpy as np MOD = 10**9 + 7 def main(): data = sys.stdin.buffer.read().split() if not data: return # 全入力を整数に変換 data = list(map(int, data)) it = iter(data) N = next(it) MAXVAL = 5000 # NumPy 配列で頻度カウント(dtype=np.int64 で十分) C = np.zeros(MAXVAL, dtype=np.int64) for _ in range(N): x = next(it) # x が MAXVAL 未満であると仮定(問題文の仕様通り) C[x] += 1 # dp 配列:dp[k] = 「k 個選んだときの通り数」 # dp[0] = 1 で初期化。以降の更新は # dp[1:] = (dp[1:] + dp[:-1] * C[i]) % MOD # というベクトル演算で行う dp = np.zeros(N + 1, dtype=np.int64) dp[0] = 1 # ここで、for ループは N 回回りますが、内側は NumPy の高速演算となるため十分高速です for i in range(N): # ここで dp の更新は「右シフトした dp[:-1] に C[i] を掛けたものを dp[1:] に加算」 dp[1:] = (dp[1:] + dp[:-1] * C[i]) % MOD # fac[k] = k! mod MOD の配列(長さ N+1)を計算 fac = np.empty(N + 1, dtype=np.int64) fac[0] = 1 for i in range(1, N + 1): fac[i] = (fac[i - 1] * i) % MOD # 最終結果は # ans = Σ_{i=0}^{N} dp[i] * fac[N - i] * ((-1)**i) (mod MOD) # (-1)**i は、偶数なら 1、奇数なら MOD-1(= -1 mod MOD)とみなせます sign = np.empty(N + 1, dtype=np.int64) sign[::2] = 1 # 偶数番目は 1 sign[1::2] = MOD - 1 # 奇数番目は MOD-1 # fac[N-i] を得るために fac 配列を逆順に fac_rev = fac[::-1] # 各項を計算して合計(mod MOD) ans = int((np.sum(dp * fac_rev % MOD * sign)) % MOD) sys.stdout.write(str(ans)) if __name__ == '__main__': main()