[ARC174E] Existence Counting 题解
记限制序列为 \(a\),排列数为 \(A_n^m\)。
对于字典序的限制,我们一位一位填,考虑第一次与 \(a\) 出现不同的是哪一位。
具体地,我们从 \(1\) 到 \(k\) 枚举 \(i\),要填的数 \(v\) 只有两种可能:
- \(v = a_i\)。
- \(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)\)。

浙公网安备 33010602011771号