跳转至

8113. 【2022.10.7联考noip模拟】Talulah

题意

给定长度为 \(n\) 的排列 \(p\),定义集合 \(S_i = \{j \mid j \ge i \land \max_{k \in [i,j]} p_k = p_j\}\)

给定 \(q\) 次询问 \(l,r\),求 \(\sum_{x,y \in [l,r]} |S_x \cap S_y|\)

\(n,q \le 2.5 \times 10^5\)

思考

考虑钦定 \(x<y\),如下图所示:

图解

发现 \(\forall i \ge y\)\(i \in S_x \Rightarrow i \in S_y\)

Proof: 因为 \(i \in S_x\),所以 \(\max_{k \in [x,i]} p_k = p_i\),因此显然 \(\max_{k \in [y,i]} p_k = p_i\),即 \(i \in S_y\)\(\square\)

因此 \(|S_x \cap S_y| = |S_x \cap [x,y)| + |S_y|\)

考虑把这两个部分分开处理,发现所有 \(|S_y|\) 即为 \(\sum_{i \in [l,r]} (i-l)|S_i|\),可以用前缀和 \(\mathrm O(1)\) 计算。

考虑计算 \(\sum_{l \le x \lt y \le r} |S_x \cap [x,y)|\),如下图所示:

图解

正难则反,考虑抛弃 \(y\) 的限制,而是计算 \(i \in S_x\) 的贡献。

发现 \(\forall i \in S_x \cap [x,r]\),对于 \(\forall y \gt i\) 都有 \(1\) 的贡献,即原式等于 \(\sum_{i \in S_x \cap [x,r]} r-i\)

发现这个不好维护,于是正难则反,考虑计算 \(\forall i \in [l,r]\)\(x \le i\) 的贡献。

\(\mathrm{pre}_i = \max_{j \lt i} {j \mid p_j \gt p_i}\),即 \(i\) 前第一个大于 \(i\) 的元素的位置,并记 \(p_0 = \infty\)

发现 \(\forall i \in [l,r]\)\(i\)\(x \in (\mathrm{pre}_i,i]\)\(r-i\) 的贡献。

由于我们不清楚 \(r\) 的值,因此我们维护 \(r\) 的系数即可。

图解

如上图,考虑用线段树维护区间加与区间和。

考虑 \(i \in [l,r]\) 这条限制,容易发现当 \(i \lt l\) 时,\(i\)\([l,r]\) 无贡献;当 \(i \gt r\) 时,如上图的 \(j\),会对 \([l,r]\) 产生多余的贡献。

因此我们把询问离线并按右端点排序,依次加点即可。

最后别忘了我们计算的是 \(x \lt y\) 的答案,剩下部分是 naive 的。

如果强制在线的话,可以用可持久化线段树 + 标记永久化解决,时间复杂度同为 \(\mathrm O((n+q) \log n)\)