如果我是作者,我会这样编写这道题的题解,力求清晰、直观且深入:
题解:冰火战士能量平衡问题
问题重述
在温度调节场景中,冰系战士和火系战士的能量消耗随温度变化:
• 冰系战士:温度 ≤ 其适应温度时才能出战,能量总和随温度升高递增(前缀和)。
• 火系战士:温度 ≥ 其适应温度时才能出战,能量总和随温度升高递减(后缀和)。
目标:选择一个温度,使得双方出战战士的总能量最小值最大化,并输出此时的总能量×2。
关键性质
-
单调性:
• 冰系能量和 f(k) 是温度 k 的非递减函数(前缀和)。
• 火系能量和 g(k) 是温度 k 的非递增函数(后缀和)。
• 答案 min 是一个单峰函数。 -
极值点:
• 最优解出现在 f(k) 和 g(k) 的交点附近,或单调性变化的边界。
算法设计
步骤1:离散化处理
• 将所有战士的适应温度离散化为唯一排名,降低值域规模。
步骤2:树状数组维护动态和
• 冰系:用树状数组 tr0
维护前缀和(温度升高时新增战士)。
• 火系:用树状数组 tr1
维护后缀和(温度升高时减少战士),通过补集转换:
• 总和 sum1
减去前缀和得到后缀和。
步骤3:寻找最优温度
-
二分法(60分做法):
• 在离散化后的温度上二分,找到最大的 k 满足 f(k) \leq g(k)。
• 检查 k 和 k+1 的 \min(f, g),取较大者。 -
树状数组上倍增(100分优化):
• 核心思想:利用树状数组的二进制跳跃特性,直接在数据结构上倍增。
• 操作:
◦ 初始化指针p = 0
,步长从 2^{20} 到 2^0 尝试扩展。
◦ 每次检查p + (1 << i)
的位置,动态累加前缀和 s_0 和后缀和 s_1。
◦ 根据 s_0 和 s_1 的大小关系调整p
,最终停在 f(k) \leq g(k) 的最大 k。
• 优势:将二分法的 O(\log n) 次查询优化为单次扫描,均摊 O(\log n) 时间。
步骤4:处理边界情况
• 无解:当所有温度下 \min(f, g) = 0 时输出 Peace
。
• 多个极值点:检查 k 和后续连续相等能量的最大温度 k’。
代码实现关键
// 树状数组上倍增找交点
int p1 = 0;
long long s0 = 0, s1 = sum1; // 初始化火系总和
for (int i = 20; i >= 0; i--) {
int np = p1 + (1 << i);
if (np > cnt) continue;
long long ns0 = s0 + tr0.get(np), ns1 = s1 - tr1.get(np);
if (ns0 <= ns1) { // 冰系能量仍≤火系,继续右移
p1 = np;
s0 = ns0, s1 = ns1;
}
}
long long f1 = s0; // 交点处的能量
// 检查下一个温度是否更优
long long f2 = 0;
if (p1 < cnt) {
f2 = min(tr0.query(p1 + 1), sum1 - tr1.query(p1 + 1));
// 可能需要找到最大的k'满足能量相同
}
复杂度分析
• 时间:O(n \log n),每个操作(插入、查询)在树状数组上耗时 O(\log n)。
• 空间:O(n),存储离散化后的温度和树状数组。
思考过程
- 暴力思路:直接枚举每个温度计算 \min(f, g),但 O(n^2) 超时。
- 单调性观察:发现 f(k) 和 g(k) 的单调性,转化为找交点。
- 数据结构选择:树状数组高效维护动态前缀/后缀和。
- 优化二分:在树状数组上倍增,避免重复计算。
为什么这样设计?
• 树状数组的倍增特性:其结构天然支持从低位到高位的跳跃,适合快速定位。
• 离散化必要性:原始温度范围大(1 \leq x \leq 10^9),离散化后值域压缩到 2 \times 10^6。
• 避免三分法:因离散化和平台区域存在,三分法可能错过极值。
典型样例分析
输入:
3
1 0 5 3 // 冰系战士,温度5,能量3
1 1 2 4 // 火系战士,温度2,能量4
1 1 4 2 // 火系战士,温度4,能量2
处理:
1. 离散化温度:[2, 4, 5]
→ 排名 1, 2, 3
。
2. 计算:
• f(1)=0, g(1)=6 → \min=0
• f(2)=0, g(2)=4 → \min=0
• f(3)=3, g(3)=2 → \min=2
• 最优温度 5
,能量 2*2=4
。
总结
本题的核心技巧:
1. 单调性转化:将最优化问题转化为函数交点问题。
2. 数据结构优化:树状数组的动态维护与高效查询。
3. 离散化与倍增:降低问题规模,利用二进制跳跃加速。
通过将问题抽象为数学模型,并合理选择数据结构,能够高效解决此类动态统计问题。