算法思路

每个发射站 i 的能量 Vi 只能被最近的、高度比它高的左、右两侧发射站接收。
对任意 i

  • 左接收站 L[i] 是离 i 最近的左侧下标满足 HL[i] > Hi
  • 右接收站 R[i] 是离 i 最近的右侧下标满足 HR[i] > Hi

于是只要把 Vi 加到 L[i]R[i] 的接收总量上,最后统计每个站的接收总量即可。

问题的核心于是转化为“求每个元素左右最近的更大元素”。这是一个经典的 单调递减栈(monotone decreasing stack)可在 O(N) 时间内完成的任务,且在遍历过程中每个元素最多进出栈一次,整体线性。

代码实现

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N;
    cin >> N;
    vector<int> H(N);
    vector<int> V(N);
    for (int i = 0; i < N; i++) {
        cin >> H[i] >> V[i];
    }

    vector<int> L(N, -1);
    vector<int> R(N, -1);
    vector<int> stk;

    for (int i = 0; i < N; i++) {
        while (!stk.empty() && H[stk.back()] <= H[i])
            stk.pop_back();
        if (!stk.empty())
            L[i] = stk.back();
        stk.push_back(i);
    }

    stk.clear();

    for (int i = N - 1; i >= 0; i--) {
        while (!stk.empty() && H[stk.back()] <= H[i])
            stk.pop_back();
        if (!stk.empty())
            R[i] = stk.back();
        stk.push_back(i);
    }

    vector<ll> E(N, 0LL);
    for (int i = 0; i < N; i++) {
        if (L[i] >= 0)
            E[L[i]] += V[i];
        if (R[i] >= 0)
            E[R[i]] += V[i];
    }

    ll max_energy = *max_element(E.begin(), E.end());
    cout << max_energy << endl;
}