前言
T4原来的题解不是给人看的。于是就有了这篇题解。
题解
我们先考虑,对于一个数 \(i\),它的对应集合 \(S_i\) 是什么。
求出 \(S_i\) 自然想到用单调栈。单调栈有一个特性,就是栈中的元素是单调的。
也就是说,压入 \(p_i\) 以后,单调栈中的元素满足 \(\forall j \in [1,top], p_j > \max_{k=j+1}^{top} p_k\)。
这个就是题目中我们的集合 \(S_i\) 满足的性质!因此,压入 \(p_i\) 以后,单调栈就是 \(S_i\)。
对于每一次询问 \([l,r]\),我们需要求出以下式子的值。
\[\sum_{l \leq x \leq r} \sum_{l \leq y \leq r} |S_x \cup S_y|
\]
自然,我们可以先运用容斥原理,把它变成交集的形式。
\[\sum_{l \leq x \leq r} \sum_{l \leq y \leq r} |S_x| + |S_y| - |S_x \cap S_y|
\]
我们先考虑前两项怎么做。我们令 \(T_i\) 为 \(|S_i|\) 的前缀和。
\[\begin{aligned}
\sum_{l \leq x \leq r} \sum_{l \leq y \leq r} |S_x| + |S_y|
&= \sum_{l \leq x \leq r} \left(\sum_{l \leq y \leq r} |S_x| + \sum_{l \leq y \leq r} |S_y| \right)
\\&= \sum_{l \leq x \leq r} \left( |S_x|\times(r-l+1) + T_r - T_{l-1} \right)
\\&= (T_r - T_{l-1})\times(r-l+1) + (T_r - T_{l-1}) \times(r-l+1)
\\&= 2\times(r-l+1)\times(T_r - T_{l-1})
\end{aligned}\]
因此我们可以用前缀和处理前两项。
我们再考虑后两项怎么做。
我们令
\[f(l_1,r_1,l_2,r_2)=\sum_{l_1 \leq x \leq r_1}\sum_{l_2 \leq y \leq r_2} |S_x \cap S_y|
\]
它满足可差分性。
\[\begin{aligned}
f(l_1,r_1,l_2,r_2)
&= \sum_{l_1 \leq x \leq r_1}\sum_{l_2 \leq y \leq r_2} |S_x \cap S_y|
\\&= \sum_{l_1 \leq x \leq n}\sum_{l_2 \leq y \leq r_2} |S_x \cap S_y| - \sum_{r_1+1 \leq x \leq n}\sum_{l_2 \leq y \leq r_2} |S_x \cap S_y|
\\&= f(l_1,n,l_2,r_2)-f(r_1+1,n,l_2,r_2)
\end{aligned}\]
题目要求我们求的是 \(f(l,n,l,r)-f(r+1,n,l,r)\)。
接下来我们考虑 \(p\) 中的一个元素 \(x\) 对答案有什么贡献。
我们把式子写出来:
\[\begin{aligned}
f(a,n,l,r)
&= \sum_{a \leq x \leq n}\sum_{l \leq y \leq r} |S_x \cap S_y|
\\&= \sum_{a \leq x \leq n}\sum_{l \leq y \leq r}\sum_{z \in S_x}[z \in S_y]
\\&= \sum_{1 \leq z \leq n}\sum_{a \leq x \leq n}\sum_{l \leq y \leq r}[z \in S_x][z \in S_y]
\end{aligned}\]
如果我们把以上这些东西看成一个坐标系,那么 \(\sum_{a \leq x \leq n}\sum_{l \leq y \leq r}[z \in S_x][z \in S_y]\) 实际上是求左下角为 \((a,l)\),右上角为 \((n,r)\) 的矩形中 \(z\) 对多少对点 \((x,y)\) 产生了贡献。
求出 \(z\) 的贡献,我们只需要知道一个数 \(z\) 在哪些集合之内即可。
根据我们之前的结论:集合 \(S_i\) 就是压入 \(p_i\) 时的单调栈。因此,如果 \(z\) 在单调栈中的时间戳是 \([l_z,r_z]\),那么这个数就会在 \([l_z,r_z]\) 所对应的集合内。这里的时间戳是指,当 \(p_t\) 压入栈中时,时间戳为 \(t\)。
因此,一个数 \(z\) 能能对左下角为 \((l_z,l_z)\),右上角为 \((r_z,r_z)\) 的正方形中的所有点都有一个 \(+1\) 的贡献。
现在有很多矩形,和很多操作 \(q_i=f(a_i,n,l_i,r_i)\),我们可以把这些操作离线,然后使用扫描线。
把操作按照 \(a_i\) 从大到小排序,然后按照横坐标从大往小扫描。也就是说,扫描线是垂直于横轴,向着负方向移动的。
对于一个正方形,我们一般把它拆成两个更新操作:
- 加入操作:当扫描线为 \(x=r_z\) 时,加入操作,区间为 \(y \in [l_z,r_z]\)。
- 撤销操作:当扫描线为 \(x=l_z-1\) 时,撤销操作,区间为 \(y \in [l_z,r_z]\)。
我们先看线段树需要维护什么信息。假设现在的扫描线是 \(x=m\),有一次询问 \(q_i=f(m,n,l_i,r_i)\)。
如果我们先不管撤销操作,考虑扫描线上的一个点 \((m,j)\)。在线段 \(y=j (m \leq x \leq n)\) 上可能会有很多加入操作,假设这些操作有 \(c_j\) 个,这些操作的横坐标分别是 \(t_{j,1},t_{j,2},\cdots,t_{j,c_j}\),那么这个点的答案为:
\[f(m,n,j,j)= \sum_{1 \leq k \leq c_j}t_{j,k}-m+1
\]
那么对于上述询问的答案就是:
\[\begin{aligned}
q_i=f(m,n,l_i,r_i)
&= \sum_{l_i \leq j \leq r_i}\sum_{1 \leq k \leq c_j}t_{j,k}-m+1
\\&= \sum_{l_i \leq j \leq r_i}\left( \sum_{1 \leq k \leq c_j}t_{j,k} -\sum_{1 \leq k \leq c_j}(m-1)\right)
\\&= \sum_{l_i \leq j \leq r_i}\left( \sum_{1 \leq k \leq c_j}t_{j,k} -c_j(m-1)\right)
\\&= \sum_{l_i \leq j \leq r_i}\sum_{1 \leq k \leq c_j}t_{j,k} - (m-1)\sum_{l_i \leq j \leq r_i}c_j
\end{aligned}\]
所以说,我们需要在线段树上维护两个信息,分别是一段区间操作的横坐标之和 \(\sum_{l_i \leq j \leq r_i}\sum_{1 \leq k \leq c_j}t_{j,k}\),和一段区间操作数量之和 \(\sum_{l_i \leq j \leq r_i}c_j\)。
对于加入操作,当扫描线为 \(x=r_z\) 时,我们只需要把 \([l_z,r_z]\) 中的 \(t\) 全部加上 \(r_z\),\(c\) 全部加上 \(1\) 即可。
现在我们考虑撤销操作。
考虑扫描线上的一个点 \((m,j)\)。在线段 \(y=j (m \leq x \leq n)\) 上也会有很多撤销操作,假设这些操作有 \(d_j\) 个,这些操作的横坐标分别是 \(t^{'}_{j,1},t^{'}_{j,2},\cdots,t^{'}_{j,d_j}\),加上原来的加入操作,那么这个点的答案为:
\[f(m,n,j,j)= \sum_{1 \leq k \leq c_j}t_{j,k}-m+1 - \sum_{1 \leq k \leq d_j}t^{'}_{j,k}-m+1
\]
以上同理,对于上述询问的答案就是:
\[\begin{aligned}
q_i=f(m,n,l_i,r_i)
&= \sum_{l_i \leq j \leq r_i}\left(\sum_{1 \leq k \leq c_j}t_{j,k}-m+1 - \sum_{1 \leq k \leq d_j}t^{'}_{j,k}-m+1\right)
\\&= \sum_{l_i \leq j \leq r_i}\sum_{1 \leq k \leq c_j}t_{j,k} - (m-1)\sum_{l_i \leq j \leq r_i}c_j -
\left(\sum_{l_i \leq j \leq r_i}\sum_{1 \leq k \leq d_j}t^{'}_{j,k} - (m-1)\sum_{l_i \leq j \leq r_i}d_j \right)
\\&= \sum_{l_i \leq j \leq r_i}\left(\sum_{1 \leq k \leq c_j}t_{j,k} - \sum_{1 \leq k \leq d_j}t^{'}_{j,k} \right)-(m-1)\sum_{l_i \leq j \leq r_i}c_j-d_j
\end{aligned}\]
因此,对于撤销操作,当扫描线为 \(x=l_z-1\) 时,我们只需要把 \([l_z,r_z]\) 中的 \(t\) 全部加上 \(-(l_z-1)\),\(c\) 全部加上 \(-1\) 即可。这样就可以使答案正确。
至此,我们就可以把这道题做完了。线段树只需要维护区间加区间求和。时间复杂度 \(O(n\log n)\)。
【完结撒花💐】
written by reinforest on 2025.4.7