这是本文档旧的修订版!
一种支持区间最值修改及各种查询的线段树。
给定一个序列,支持下述三种操作:
考虑建立线段树,维护区间最大值,区间最大值个数,区间次大值,区间和。
对修改操作,如果 $v$ 不小于区间最大值,则该操作没有意义,直接返回,否则先进行普通区间修改操作。
当普通区间修改操作遇到当前区间被包含于修改区间时,如果 $v$ 的大于区间次大值,则直接修改区间最大值,同时打上懒标记。
如果 $v$ 不大于区间次大值,则暴力修改子树。发现修改过程本质是 $\text{dfs}$,而 $\text{dfs}$ 时间复杂度等于遍历结点个数。
定义一个结点所代表区间的不同数值所构成的集合为该结点的数集,则暴力修改至少会合并该结点的最大值和次大值,于是该结点数集大小减小。
普通区间修改操作至多会使该结点的数集增加一个值,但普通区间修改的结点只有 $O(\log n)$ 个。
初始时所有结点的数集大小和为 $O(n\log n)$,于是修改操作的总复杂度为 $O((n+m)\log n)$。
对查询操作,和普通区间查询操作完全相同。
给定一个序列,支持下述三种操作:
先只考虑操作 $1\sim 4$。对区间加操作,直接按普通区间加处理即可。但注意区间加会修改操作最值操作的懒标记,最大值和次大值。
另外区间加需要特判最值操作的懒标记和区间次大值不存在的情况。区间加操作本身的复杂度显然为 $O(\log n)$。
考虑区间加操作对区间最值操作的影响。对某个结点,不难发现该结点的数集大小增加的最大可能值等于区间加过程中遍历的该结点的子节点数。
一个结点在一次区间加过程中最多有 $O(\log n)$ 个子结点被遍历,而一次区间加过程最多遍历 $O(\log n)$ 个结点。
所以一次区间加操作最多使数集总和增加 $O(\log^2 n)$,所以总时间复杂度变为 $O(n\log n+m\log^2 n)$。
接下来考虑操作 $1,3,4,5$。发现只需要维护加法懒标记的历史最大值即可维护区间历史最大值。
接下来考虑操作 $1\sim 5$。发现区间最值操作可以转化为对区间最值单独操作的特殊区间加法。
于是考虑对每个结点维护区间最值懒标记,区间最值的历史最值懒标记,区间非最值懒标记,区间非最值的历史最值懒标记。
总时间复杂度仍然为 $O(n\log n+m\log^2 n)$。
给定一个长度为 $n$ 序列,支持下列操作:
对加法操作,考虑维护区间当前加法懒标记和区间历史最大加法懒标记。对赋值操作,考虑维护区间当前赋值懒标记和区间历史最大赋值懒标记。
考虑标记下放的本质,即将当前区间的所有操作序列添加到子区间操作序列的后面,同时维护该操作对答案的影响。一个策略为合并操作。
发现将加法操作添加到加法操作后面可以直接叠加,可以合并为一个加法操作。
将赋值操作添加到加法操作无法合并,留下一个赋值操作。
将赋值操作添加到赋值操作后面直接覆盖即可,可以合并为一个赋值操作。
将加法操作添加到赋值操作后面可以理解为更新上一次的赋值操作,最后合共为一个赋值操作。
于是整个操作序列最后可以合并为一个加法操作和一个赋值操作。懒标记下放的同时维护历史最值即可,时间复杂度 $O(n+q\log n)$。
给定序列 $A$。定义 $G(i,j)=\text{gcd}(a_i,a_{i+1}\cdots a_j),M(i,j)=\max(a_i,a_{i+1}\cdots a_j)$,求
$$ \sum_{i=1}^n\sum_{j=i}^nG(i,j)M(i,j) $$
考虑计算 $\sum_{j=1}^iG(i,j)M(i,j)$ 的贡献。
发现 $1\le j\le i$ 的 $G(i,j)$ 只有 $O(\log v)$ 个取值,同时有 $G(i,j)=\text{gcd}(G(i-1,j),a_i)$。
于是可以 $O(\log n\log v)$ 维护所有不同的 $G(i,j)$。不同取值的 $G(i,j)$ 将 $[1,i]$ 划分为若干区间。
又有 $M(i,j)=\max (M(i-1,j),a_i)$,于是可以吉司机线段树维护区间最值操作下的区间和。
对每个被划分的区间直接查询求和即可,时间复杂度 $O(\log n\log v)$。于是总时间复杂 $O(n\log n\log v)$。