This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
using idata = vector<int>;
using bdata = vector<bool>;
const int START = 0;
const int END = 1;
const int QUERY = 2;
struct Event {
int pos, type, id;
Event (int pos, int type, int id) : pos(pos), type(type), id(id) {}
bool operator< (const Event &other) const {
if (pos == other.pos) return type < other.type;
return pos < other.pos;
}
};
using vEvent = vector<Event>;
struct SGData {
bool enabled = false;
int mx = -1; int mn = -1;
void merge (SGData &left, SGData &right) {
enabled = left.enabled | right.enabled;
if (!left.enabled) {
mx = right.mx;
mn = right.mn;
} else if (!right.enabled) {
mx = left.mx;
mn = left.mn;
} else {
mx = max(left.mx, right.mx);
mn = min(left.mn, right.mn);
}
}
};
struct SegTree {
vector<SGData> tree;
int size, start, height;
SegTree (idata heights) {
size = heights.size();
height = ceil(log2(size));
start = 1 << height;
tree.resize(start << 1);
for (int i = 0; i < size; i ++) {
tree[i + start].mx = heights[i];
tree[i + start].mn = heights[i];
}
}
void toggle (int index) {
index += start;
tree[index].enabled = !tree[index].enabled;
index >>= 1;
while (index != 0) {
tree[index].merge(tree[index * 2], tree[index * 2 + 1]);
index >>= 1;
}
}
SGData query (int l, int r) {
l += start;
r += start;
SGData local;
SGData result;
while (l < r) {
if ((l & 1) == 1) { local.merge(result, tree[l]); result = local; }
if ((r & 1) == 0) { local.merge(result, tree[r]); result = local; }
l = (l + 1) >> 1;
r = (r - 1) >> 1;
}
if (l == r) { local.merge(result, tree[l]); result = local; }
return result;
}
};
vEvent events;
idata heights;
idata left_q;
idata right_q;
bdata enabled;
int main () {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N;
cin >> N;
heights.resize(N);
left_q .resize(N);
right_q.resize(N);
for (int i = 0; i < N; i ++) {
int h, a, b;
cin >> h >> a >> b;
heights[i] = h;
left_q [i] = i + a;
right_q[i] = i + b;
events.push_back(Event( i - b, START, i ));
events.push_back(Event( i - a + 1, END, i ));
events.push_back(Event( i, QUERY, i ));
}
sort(events.begin(), events.end());
int Q; cin >> Q;
enabled.resize(N);
SegTree tree(heights);
for (int q = 0; q < Q; q ++) {
int l, r;
cin >> l >> r;
l --; r --;
int res = -1;
for (Event &event : events) {
if (event.type == START) {
tree.toggle(event.id);
} else if (event.type == END) {
tree.toggle(event.id);
} else {
if (event.id < l) continue ;
if (event.id > r) continue ;
if (left_q[event.id] > r) continue ;
SGData data = tree.query(left_q[event.id], min(r, right_q[event.id]));
if (!data.enabled) continue ;
res = max(res, data.mx - heights[event.id]);
res = max(res, heights[event.id] - data.mn);
}
}
cout << res << "\n";
}
}
# | 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... |