📌  相关文章
📜  具有最大 MEX 前缀数组和的数组的排列计数(1)

📅  最后修改于: 2023-12-03 14:50:07.308000             🧑  作者: Mango

具有最大 MEX 前缀数组和的数组的排列计数
介绍

“MEX 前缀数组和”是指一个数组的前缀中,MEX(Minimum excluded number)最大的值与该前缀的数组和的和。现给定一个长度为 $n$ 的正整数排列,求具有最大 MEX 前缀数组和的排列的个数。

思路

我们可以设 $f_i$ 为以 $i$ 结尾的具有最大 MEX 前缀数组和的数组的排列计数,那么我们可以考虑当将一个数 $x$ 插入到排列前面时,对答案的影响为:

  1. $x > f_{i-1}$,则无论怎样调整后面的数,MEX 前缀都不会发生改变,影响 MEX 前缀数组和的只有 $x$,设 $sum_i$ 表示 $[1,i]$ 的和,则有 $f_i = sum_{i-1}+x$;
  2. $x \leq f_{i-1}$,那么就需要调整一些数来维护 MEX 前缀的值,我们设 $p$ 为 $x$ 在 $[1,i-1]$ 中第一次出现的位置,那么就需要将 $[p+1,i-1]$ 中大于 $x$ 的数取出,插入到 $p$ 的位置,这样就会减少一些后缀的 MEX 前缀,于是我们可以得到:

$$f_i = \sum_{j=1}^{p-1}f_j + \sum_{j=p+1}^{i} (a_j \geq a_p) \times a_j + x$$

其中 $\sum_{j=p+1}^{i} (a_j \geq a_p) \times a_j$ 表示将 $[p+1,i]$ 中大于 $x$ 的数插入到 $p$ 的位置所导致的影响。

综上,我们考虑枚举 $x$,再枚举 $p$,根据 $x$ 与 $f_{i-1}$ 的大小关系确定 $f_i$ 的值即可。时间复杂度 $\mathcal{O}(n^2)$。

当然,我们可以通过维护 $f_1,f_2,\cdots,f_{i-1}$ 的最值来消去枚举 $p$ 的部分,这样时间复杂度就被优化到了 $\mathcal{O}(n \log_2 n)$,但此处不再阐述。

代码
MOD = 998244353

n = int(input())
a = [int(x) for x in input().split()]
f = [0] * (n + 1)
sum_ = [0] * (n + 1)
for i in range(1, n+1):
    sum_[i] = sum_[i-1] + i

ans = 0
for x in range(1, n+1):
    rev = [i for i in range(n) if a[i] >= x]
    dp = [0] * (n-rev[0]) # f_1, f_2, ..., f_{p-1}
    s = sum(a[i] for i in rev)
    for i in range(rev[0], n):
        if a[i] < x:
            continue
        j = bisect_right(rev, i)
        p = rev[j-1]
        if a[p] < x:
            continue
        if j == 1:
            dp[j-1] = sum_[i-1] + x
        else:
            k = j-2
            while k >= 0 and rev[k] >= p:
                k -= 1
            val = (dp[k] + s - sum(a[i] for i in rev[k+1:j])) % MOD
            dp[j-1] = val + sum_[i-1] + x
        ans = (ans + dp[j-1]) % MOD

print(ans)
参考文献
  1. AT4938 【MEX Maximum】