이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 100;
class SegmentTree {
private:
int sz;
vector<int> C; // C[i] = H[i] if i is active, -INF otherwise. We hold maximum C for each node.
vector<int> D; // D[i] = max(C[i] - H[j]) so far. We hold maximum D for each node.
vector<int> L; // lazy propagation, we have to update D[k] = max(D[k], C[k] - L) on segment
void Push(int n) {
if (L[n] != INF) {
L[n * 2] = min(L[n * 2], L[n]); // in order to maximize C[k] - L
L[n * 2 + 1] = min(L[n * 2 + 1], L[n]);
D[n * 2] = max(D[n * 2], C[n * 2] - L[n]); // lazy propagation
D[n * 2 + 1] = max(D[n * 2 + 1], C[n * 2 + 1] - L[n]);
L[n] = INF;
}
}
void Pull(int n) {
C[n] = max(C[n * 2], C[n * 2 + 1]); // C helps in lazy propagation to update maximum C - L quickly
D[n] = max(D[n * 2], D[n * 2 + 1]);
}
void PointSetUpdate(int n, int tl, int tr, int k, int H) {
if (tl == tr) return void(C[n] = H);
Push(n);
int mid = (tl + tr) / 2;
if (k <= mid) {
PointSetUpdate(n * 2, tl, mid, k, H);
} else {
PointSetUpdate(n * 2 + 1, mid + 1, tr, k, H);
}
Pull(n);
}
void RangeUpdate(int n, int tl, int tr, int l, int r, int H) {
if (tr < l || r < tl || tl > tr || l > r) return;
if (l <= tl && tr <= r) {
D[n] = max(D[n], C[n] - H);
L[n] = min(L[n], H);
return;
}
Push(n);
int mid = (tl + tr) / 2;
RangeUpdate(n * 2, tl, mid, l, r, H);
RangeUpdate(n * 2 + 1, mid + 1, tr, l, r, H);
Pull(n);
}
int RangeMaximumQuery(int n, int tl, int tr, int l, int r) {
if (tr < l || r < tl || tl > tr || l > r) return -INF;
if (l <= tl && tr <= r) return D[n];
Push(n);
int mid = (tl + tr) / 2;
return max(RangeMaximumQuery(n * 2, tl, mid, l, r),
RangeMaximumQuery(n * 2 + 1, mid + 1, tr, l, r));
}
public:
SegmentTree(int n) : sz(n) {
C.assign(4 * sz, -INF);
D.assign(4 * sz, -INF);
L.assign(4 * sz, INF);
}
void PointSetUpdate(int k, int H) { // set C[k] = H
return PointSetUpdate(1, 0, sz - 1, k, H);
}
void RangeUpdate(int l, int r, int H) { // for each k, l <= k <= r, D[k] = max(D[k], C[k] - H)
return RangeUpdate(1, 0, sz - 1, l, r, H);
}
int RangeMaximumQuery(int l, int r) { // RMQ on the array D
return RangeMaximumQuery(1, 0, sz - 1, max(l, 0), r);
}
};
vector<int> answer;
void Solve(int N, int Q, vector<int> H, vector<int> A, vector<int> B,
vector<int> L, vector<int> R) {
int a;
vector<vector<pair<int, int>>> events(N); // (type, x)
// type = 1 -> set C[x] = H[x]
// type = 2 -> set C[x] = -INF
// type <= 0 -> query (x, current), query id is -type
for (int i = 0; i < N; i++) {
int l = i + A[i], r = i + B[i] + 1; // antenna i is active on segment [l, r)
if (l < N) events[l].emplace_back(1, i);
if (r < N) events[r].emplace_back(2, i);
}
for (int i = 0; i < Q; i++) {
events[R[i]].emplace_back(-i, L[i]);
}
SegmentTree seg(N);
for (int t = 0; t < N; t++) {
reverse(begin(events[t]), end(events[t]));
while (!events[t].empty()) { // updates
if (events[t].back().first <= 0) break;
int type = events[t].back().first;
int x = events[t].back().second;
events[t].pop_back();
if (type == 1) {
seg.PointSetUpdate(x, H[x]);
} else {
seg.PointSetUpdate(x, -INF);
}
}
// for k, t - B[t] <= k <= t - A[t], we update D[k] = max(D[k], C[k] - H[t])
seg.RangeUpdate(t - B[t], t - A[t], H[t]);
while (!events[t].empty()) { // queries
int ql = events[t].back().second;
int qr = t;
int qi = -events[t].back().first;
events[t].pop_back();
answer[qi] = max(answer[qi], seg.RangeMaximumQuery(ql, qr));
}
}
}
void Solve() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int N;
cin >> N;
vector<int> H(N), A(N), B(N);
for (int i = 0; i < N; i++) {
cin >> H[i] >> A[i] >> B[i];
}
int Q;
cin >> Q;
vector<int> L(Q), R(Q);
for (int i = 0; i < Q; i++) {
cin >> L[i] >> R[i];
L[i]--, R[i]--;
}
answer.assign(Q, -1);
auto Reverse = [&]() {
// reverse the array
reverse(begin(H), end(H));
reverse(begin(A), end(A));
reverse(begin(B), end(B));
for (int i = 0; i < Q; i++) {
L[i] = N - 1 - L[i];
R[i] = N - 1 - R[i];
swap(L[i], R[i]);
}
};
Solve(N, Q, H, A, B, L, R);
Reverse();
Solve(N, Q, H, A, B, L, R);
}
void Write() {
for (auto &ans : answer) {
cout << ans << "\n";
}
}
int main() {
Solve();
Write();
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
antennas.cpp: In function 'void Solve(int, int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
antennas.cpp:90:7: warning: unused variable 'a' [-Wunused-variable]
int a;
^
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |