[ARC174E] Existence Counting 题解

记限制序列为 \(a\),排列数为 \(A_n^m\)

对于字典序的限制,我们一位一位填,考虑第一次与 \(a\) 出现不同的是哪一位。

具体地,我们从 \(1\)\(k\) 枚举 \(i\),要填的数 \(v\) 只有两种可能:

  1. \(v = a_i\)
  2. \(v < a_i\)\(v\) 未在 \(a_1, a_2, \cdots ,a_{i-1}\) 中出现过。

对于 case 1,我们记 \(suf_i\) 表示前 \(i-1\) 位与 \(a_i\) 填得一样,第 \(i\) 位开始不做限制(只要互不相同),填出的序列字典序小于等于 \(a\) 的方案数。
\(num_i\) 为前 \(i\) 位,小于 \(a_i\) 但之前未选的数的个数,树状数组轻松处理。
若第 \(i\) 位填得一样,那么贡献为 $ suf_{i+1}$。若第 \(i\) 位填得小,那么后面随便填,贡献为 \(num_i \times A_{n-i}^{k-i}\)。故 \(suf_i = suf_{i+1} + num_i \times A_{n-i}^{k-i}\)

那么 case 1 的情况即是:\(ans_{a_i} \gets ans_{a_i} + suf_{i+1}\),其他数的贡献不用算。

再看 case 2。这时因为已经有当前填的数 \(v<a_i\) 了,故后面随便填。既然随便填,就要把所有数的贡献全部算算。
对于当前一个未选的数 \(x\)

  • \(x < a_i\),分为第 \(i\) 位填 \(x\) 和第 \(i\) 位不填 \(x\) 两种情况。
    \(i\) 位填 \(x\),就是第 \(i\) 位定死,后面随便填;否则,第 \(i\) 位填除了 \(x\),有 \(num_i - 1\) 种选择,后面随便填。至于 \(k-i\) 因子,是枚举 \(x\) 放哪。
    \(ans_x \gets ans_x + 1 \times A_{n-i}^{k-i} + (num_i - 1) \times (k-i) \times A_{n-i-1}^{k-i-1}\)
  • \(x \ge a_i\),那第 \(i\) 位有 \(num_i\) 种选择,后面随便填。
    \(ans_x \gets ans_x + num_i \times (k-i) \times A_{n-i-1}^{k-i-1}\)

问题来了,如何快速处理这一串更新呢?
注意到他们实际上都是区间加,用树状数组区间修改,最后单点查询。
那如何将已选的数刨掉贡献呢?
我们增加一个【锁定】操作,在每次 case 1 的时候就会有一个数已选,在这时候将 \(ans\) 确定下来,之后不接受树状数组的单点查询,也就刨掉了之后的贡献操作。
最后,将没有【锁定】的数的答案设为树状数组单点查询的结果即可。

时间复杂度 \(O(k \log n)\)

submission.

posted @ 2025-03-08 17:54  Water_M  阅读(17)  评论(0)    收藏  举报