QOJ#5098. 第一代图灵机
兔队线段树题。
记 \(\{a_i\}\) 的前缀和为 \(\{S_i\}\),记距离 \(i\) 位置最近的颜色相同位置为 \(pre_i\),那当钦定某个点 \(i\) 为右端点时,左端点最小可以为 \(\max\limits_{1\le j\le i}\{pre_j\} + 1\)。
考虑对于线段树上每个结点 \(p\),记其对应的区间为 \([l_p, r_p]\),中点为 \(mid_p\)。我们在该节点维护 \(mx_p = \max\limits_{l_p\le i\le mid_p}\{pre_i\} + 1\),再维护仅考虑区间 \([l, r]\) 时以 \((mid, r]\) 为右端点的区间的最大权值 \(val_p\),即 \(\max\limits_{mid<i\le r}\{S_i - S_{\max_{l\le j\le i}\{pre_j\}}\}\)。
对于询问 \([l, r]\) 可以拆到若干个结点上,记 \(c(x, p)\) 表示询问以 \([l_p, r_p]\) 中的点为右端点,左端点不小于 \(x\) 的最大权值,那么可以分类讨论:
当 \(x>mx_p\) 时,\(c(x,p) = c(x, rson(p))\);
当 \(x \le mx_p\) 时,右半区间原来可以取到的显然仍然可以全部取到,故 \(c(x, p) = \max(c(x, lson(p)), val_p)\)。
最后会到哪里捏?第一个 \(pre_i\ge x\) 的点,它的前驱 \(i-1\) 就是满足 \(\max\limits_{1\le j\le i-1}\{pre_j\} < x\) 的最大 \(i - 1\),这就是左端点为 \(x\) 时右端点最大的点。
再看看这个询问喵,前缀 \(pre\) 的限制是怎么做的喵,结点外的前缀 \(pre\) 直接利用 \(x\) 来限制,结点内的 \(pre\) 在维护结点信息时就已经被限制好啦。
怎么 pushup 捏,更简单了喵,直接 \(val_p = c(mx_p, rson(p))\) 喵。
时间复杂度两只 \(\log\) 喵。