省选 数据结构选做 1
Luogu P6225
异或每个子区间的值必定会有抵消的部分,容易发现 \([l, r]\) 内有贡献当且仅当 \(l, r\) 奇偶性相同,此时从 \(l\) 开始错位贡献到答案里。树状数组分下标奇偶存异或结果维护答案即可。
Luogu P6619
最优的 \(k\) 必定取在某名战士的温度上,因为火战士不能超过某个特定温度而冰展示不能低于某个特定温度,有效范围是 \([\min(t_{\rm ice}), \max(t_{\rm fire})]\) 且能量函数在该范围内呈阶梯状,最大值必定出现在阶梯状的转折点即某个战士的具体温度上。离散化战士的温度,答案在战士的温度当中找。
令 \(f1(k) = \sum_{i \in \text{ice}, x_i \geq k} y_i, f2(k) = \sum_{i \in \text{fire}, x_i \geq k} y_i\)。则要找一个 \(k\) 使得 \(\min(f1(k), f2(k))\) 最大。注意到,\(f1(k)\) 单调不降、\(f2(k)\) 单调不增,注意到两条函数图像相交成 \(X\) 状,我们取 \(X\) 的下面两条曲线为函数 \(g(k) = \min(f1(k), f2(k))\) 的图像,显然 \(f1(k), f2(k)\) 相交时取到最大值,但注意到 \(k\) 只能取整数,所以有两种可能的最优的 \(k\):最大的 \(k\) 使得 \(f1(k) \lt f2(k)\) 或最小的 \(k\) 使得 \(f1(k) \geq f2(k)\)。这显然是一个二分模型。考虑上数据结构维护一下 \(f1, f2\),支持区间加单点查。
冰系战士是处理后缀,火系战士处理前缀,复杂度是 \(O(n \log^2 n)\) 的,考虑把这个二分丢到线段树或者树状数组上优化掉一只 \(\log\)。维护每个区间左右端点的 \(f1(l), f2(l), f1(r), f2(r)\)。具体地,做三次二分:找到最大的 \(k\) 使得 \(f1(k) \lt f2(k)\);找到最小的 \(k\) 使得 \(f1(k) \geq f2(k)\),本质上就是 \(k_1 + 1\)。根据题目要求,如果求出来的两个最大价值相等,带入这个价值再次二分找到对应价值下最靠后的一个 \(k\)。线段树上二分的常数太大了,一个由这个题引入的做法是树状数组上二分(倍增)。
在树状数组上,从大到小枚举当前节点的 \(2^{\log n}, \dots, 2^{0}\) 级祖先向上跳,每次往前跳 \(2^i\) 个位置,检查是否可行,如果可行就跳否则不变,注意到由于我们的枚举是从大到小的,所以 \(lowbit(j) \gt 2^i, lowbit(j + 2^i) = 2^i\)。由于树状数组上位置 \(j\) 存放的是 \([i - lowbit(i) + 1, i]\) 的信息,那么 \(j + 2^i\) 中保存的是 \([j + 1, j + 2^i]\) 中的信息,我们直接检查 \(j + 2^{i}\) 内的数是否合法。
总的来说,树状数组维护 \(f1(k), f2(k)\),区间修单点改,上树状数组和差分维护,记得离散化。对于后缀加一般维护即可,前缀加记录一个全局的 \(\Delta\) 和减去后缀就得到前缀。

浙公网安备 33010602011771号