一种可快速合并的信息
建立坐标系,\(x\) 作为输入,\(y\) 作为输出
假如这种系统形如:一段水平线 + 一段 \(k = 1\) 的直线 + 一段水平线
那么这种结构在级联以后是可以快速合并的(E.g. 一个连续的序列,将前一个的输出作为后一个的输入)
具体来说,这个系统可以直接用两个拐点的信息来表示
struct Node { int x1, y1, x2, y2; };
int f(int x, Node a) { // 返回一个系统 a 在 x 处的输出 y
auto [x1, y1, x2, y2] = a;
if (x <= x1) return y1;
if (x >= x2) return y2;
return x - x1 + y1;
}
神奇(神秘)的是,合并后,这个系统依然可以用两个拐点表示出来!
我们只需要讨论出最终横轴上 \(x\) 的位置,然后通过 \(\operatorname{f()}\) 映射求出 \(y\) 就可以得到最终系统
Node operator+(const Node &a, const Node &b) {
Node res;
res.x1 = max(a.x1, b.x1 - a.y1 + a.x1);
res.x2 = min(a.x2, b.x2 - a.y1 + a.x1);
res.y1 = f(f(res.x1, a), b);
res.y2 = f(f(res.x2, a), b);
return res;
}
如果我们需要查询一个区间的级联情况,可以用线段树(点集划分)来快速维护。
因此可以解决形如 \(\min(\text{Bound}_1, val+a_i), \max(\text{Bound}_2, val+a_i)\) 作为信息 \(D\),进行级联的问题
如果是 \(M\) 的话则可以考虑伟大 $ \color{Black} \text{j} \color{red} \text{iry_2}$ 的 \(\text{seg beats}\)
例题 2023 CCPC 秦皇岛热身赛 C. Robot / 2022 CCPC 华为云计算挑战赛 1004 机器人