|
|
Pro4372 区间 题解Sol 1我们从左往右扫描离散化出来的线段 $i$(设当前点权为 $v_i$)。维护一个集合 $S$,表示覆盖这条线段的区间的编号。 对于一个询问 $[L,R]$ 若 $f(L,R)$ 包含这条线段,则存在 $x\in S$ 满足 $x\in [L,R]$。 不妨倒过来,对于当前的 $x\in S$,我们让所有满足 $L\le x,R\ge x$ 的二维点 $(L,R)$ 加上点权 $v_i$。 这样显然会算重,因为可能存在 $x,y\in S,x,y\in [L,R]$,这样 $v_i$ 就被算两次以上了。 考虑去重,对于一个询问 $[L,R]$ 让最小的符合条件的 $x$ 产生贡献,即如果同时存在两个 $x,y\in S$ 产生正贡献,就产生一次负贡献。 具体的,我们用 set 来维护 $S$,每次找到 $x$ 的前倾 $y$,让所有满足 $L\le y,R\ge x$ 的二维点 $(L,R)$ 加上点权 $-v_i$。 我们对于每一个线段都要这样做一次,复杂度就爆炸了,考虑对于每一个元素统一算贡献。 考虑第一类正贡献,设 $x$ 在第 $p$ 条线段加入 $x$,第 $q+1$ 条线段离开 $x$。则对所有 $L\le x,R\ge x$ 的点加上 $\sum_{i=p}^q v_i$。 对于第二类负贡献,我们也可以记录每一对前倾后继产生的时间区间 $[p,q]$,然后减去负贡献即可。在加入新的前倾后继关系。 于是我们转化到这样一个问题: 1. 给定若干 $(x,y,v)$,将所有 $L\le x,R\ge y$ 的点 $(L,R)$ 加上 $v$。(这一类操作的数量是 $O(n)$ 的)。 2. 查询满足 $A\le L\le R\le B$ 的所有点权之和。 不妨考虑一个操作 $(x,y,v)$ 对 $[A,B]$ 的贡献,为 $(x-A+1)(B-y+1)v$,令 $A'\gets A+1,B'\gets B+1$,则 $(x-A)(B-y)v=(Ay+Bx-AB-xy)v$。 因为 $A',B'$ 可以看作常数,所以我们做离线二维数点,同时维护 $\sum v,\sum xv,\sum yv,\sum xyv$ 即可。 时间复杂度为 $O(n\log n)$。 Sol 2将 $[l_i,r_i]$ 称为区间,$[A,B]$ 称为询问。扫描区间的下标。 设当前扫到了 $R$,则当前数组 $v_i$ 表示 $f(i,R)$。则当 $R=B$ 时查询 $[A,B]$ 就是询问所有 $i\in [A,B],v_i$ 的历史和。 考虑如何维护扫描过程中 $v_i$,设 $1\sim R$ 的所有区间中最后一个覆盖线段 $i$ 个编号是 $p_i$,则当前线段 $i$ 会对 $v_{1\sim p_i}$ 做贡献。 每次扫描线的右端点移动,新加入一个区间,会改变一些 $p_i$,设原来 $p_i=x$,后来 $p_i=y$,则这次移动会对 $v_{x+1\sim y}$ 新产生贡献。 每次都是覆盖一段区间,可以用珂朵莉树维护,改变一个颜色段的 $p_i$ 可以用一次区间加完成,而这样的区间加只有 $O(n)$ 次。 然后选择心怡的维护历史和的方法即可,例如维护当前完成的操作数 $T$,当前数组 $A$,设历史和数组为 $B$,再维护一个 $C_i=B_i-A_iT$,则只维护 $A,C$ 即可维护 $B$。 时间复杂度为 $O(n\log n)$。
题目4372 区间
AAAAAAAAAA
1
评论
2026-04-06 20:24:58
|