社区讨论

13分 求调

P14343[JOISC 2019] 两个天线 / Two Antennas参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mi0vht0x
此快照首次捕获于
2025/11/16 06:43
4 个月前
此快照最后确认于
2025/11/16 13:40
4 个月前
查看原帖
https://www.luogu.com.cn/record/247267664
CPP
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 2e5 + 5;

struct Pair {
    int x, y, cost;
    Pair(int x, int y, int cost) : x(x), y(y), cost(cost) {}
};

struct Query {
    int L, R, idx;
    Query(int L, int R, int idx) : L(L), R(R), idx(idx) {}
    bool operator<(const Query& other) const {
        return R < other.R;
    }
};

int N, Q;
int H[MAXN], A[MAXN], B[MAXN];
vector<Pair> pairs;
vector<int> ans;

// 线段树用于区间最大值查询
struct SegmentTree {
    vector<int> tree;
    int n;
    
    SegmentTree(int size) {
        n = 1;
        while (n < size) n <<= 1;
        tree.assign(2 * n, -1);
    }
    
    void update(int pos, int val) {
        pos += n;
        if (tree[pos] >= val) return;
        tree[pos] = val;
        for (pos >>= 1; pos >= 1; pos >>= 1) {
            int new_val = max(tree[2*pos], tree[2*pos+1]);
            if (tree[pos] == new_val) break;
            tree[pos] = new_val;
        }
    }
    
    int query(int l, int r) {  // [l, r]
        l += n; r += n;
        int res = -1;
        while (l <= r) {
            if (l % 2 == 1) res = max(res, tree[l++]);
            if (r % 2 == 0) res = max(res, tree[r--]);
            l >>= 1; r >>= 1;
        }
        return res;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> H[i] >> A[i] >> B[i];
    }
    
    // 预处理所有通信对
    for (int x = 1; x <= N; x++) {
        int start_y = x + A[x];
        int end_y = min(x + B[x], N);
        if (start_y > end_y) continue;
        
        for (int y = start_y; y <= end_y; y++) {
            // 检查 y 是否能与 x 通信
            int dist = y - x;
            if (dist >= A[y] && dist <= B[y]) {
                pairs.emplace_back(x, y, abs(H[x] - H[y]));
            }
        }
    }
    
    // 按 y 坐标排序通信对
    sort(pairs.begin(), pairs.end(), [](const Pair& a, const Pair& b) {
        return a.y < b.y;
    });
    
    cin >> Q;
    ans.assign(Q, -1);
    vector<Query> queries;
    
    for (int i = 0; i < Q; i++) {
        int L, R;
        cin >> L >> R;
        queries.emplace_back(L, R, i);
    }
    
    // 按 R 坐标排序查询
    sort(queries.begin(), queries.end());
    
    // 离线处理
    SegmentTree st(N);
    int pair_ptr = 0;
    
    for (const Query& q : queries) {
        // 将所有 y <= q.R 的通信对加入线段树
        while (pair_ptr < pairs.size() && pairs[pair_ptr].y <= q.R) {
            st.update(pairs[pair_ptr].x, pairs[pair_ptr].cost);
            pair_ptr++;
        }
        
        // 查询 [q.L, q.R-1] 范围内的最大值
        ans[q.idx] = st.query(q.L, q.R - 1);
    }
    
    for (int a : ans) {
        cout << a << "\n";
    }
    
    return 0;
}
那个大师教教我把

回复

1 条回复,欢迎继续交流。

正在加载回复...