题解:P11625 [迷宫寻路 Round 3] 迷宫寻路大赛

· · 题解

本题解提供离线+树状数组+双指针做法,代码请根据思路自行实现。

请务必读完解题思路。

题目回顾

给定 n, c, d\{a\},你有 q 次询问,每次给出 l, r,求:

\sum_{l \le x \le y \le r}[c \le \text{inv}(x, y) \le d].

解题思路

考虑转换原式。

\sum_{l \le x \le y \le r}[c \le \text{inv}(x, y) \le d] = \sum_{l \le x \le y \le r} [\text{inv}(x, y) \le d] - \sum_{l \le x \le y \le r} [\text{inv}(x, y) \le c - 1].

接下来求解 \displaystyle \sum_{l \le x \le y \le r} [\text{inv}(x, y) \le d]

定义 L_{d}(r) = \min \{l \mid \text{inv}(l, r) \le d\}\text{cnt}_{d}(r) = r - L_{d}(r) + 1\text{ps}_{d}(r)\text{cnt}_{d}(r) 的前缀和。

对于这部分,我们对 dc - 1 分别进行一次这样的计算。

至此,此部分求解完毕,接下来,我们思考一个问题:如何从上述信息,得到「区间 [l,r] 内,有多少子区间的逆序对 \le d」?

固定 r,若我们只关心「右端点 = r」的子区间,逆序对 \le d 的那些,其左端点 x 满足:

x \ge L_d(r).

故此时子区间数量为:

r - L_d(r) + 1 = \text{cnt}_d(r).

是现在我们只想要「左端点 x \ge l 且右端点为 r」的子区间,这些子区间的数量应该是:

f_d(r, l) = \begin{cases} \text{cnt}_d(r), &\quad L_d(r) \ge l,\\ r - l + 1, &\quad L_d(r) < l. \\ \end{cases}

那么我们再对 [l, r] 中的 f_d(k, l) 求和,便可得区间 [l, r] 内、右端点为 r 的所有子区间中满足逆序对 \le d 的数量。

\begin{aligned} \sum_{k = l} ^ r f_d(k, l) &= \sum_{k = l} ^ r \text{cnt}_d(k) - \sum_{k \in S}\left[\text{cnt}_d(k) - (k - l + 1)\right] \\ &=[\text{ps}_d(r) - \text{ps}_d(l - 1)] - \sum_{k \in S}[l - L_d(k)]. \end{aligned}

其中 S = \{k \in [l, r] \mid L_d(k) < l\}

接下来引入两个变量 y_{l, r}z_{l, r} 用于求解 \displaystyle\sum_{k \in S}[l - L_d(k)]

y_{l, r} = \sum_{k \in [l, r], L_d(k) < l}1. z_{l, r} = \sum_{k \in [l, r], L_d(k) < l} L_d(k).

此时 \displaystyle\sum_{k \in S}[l - L_d(k)] = l \times y_{l, r} - z_{l, r}

那么 y_lz_l 该如何求解?我们发现 L_d(k) < l 这个条件的存在增加了题目难度,那我们不妨开一个桶 bb_x 记录所有 L_d(k) = x 的位置 k,处理询问时将 x < lb_x 中的位置加入便可以方便地处理掉这个限制。

接下来,我们开两个树状数组 \text{fc}\text{fv} 分别维护 y_{l, r}z_{l, r},加入 b_x 的位置时分别单点加 1L_d(k) 即可。

同理,我们对 dc - 1 分别做一次。

最后,设我们处理出来的答案为 \text{ans}_d(i)\text{ans}_{c - 1}(i),直接输出 \text{ans}_d(i) - \text{ans}_{c - 1}(i) 即可。

时间复杂度分析

可以轻松处理 n, q \le 5 \times 10^5 的数据。

代码实现

请自行实现。