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 <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class SegmentTree {
public:
SegmentTree(const vector<int> &A): m_size(A.size()), m_data(m_size * 4) {
build(1, 1, m_size, A);
}
void update(int from, int to, int add) {
update(1, 1, m_size, from, to, add);
}
int query(int from, int to) {
return query(1, 1, m_size, from, to, 0);
}
private:
struct Node {
int max = 0;
int maxadd = 0;
int best = 0;
};
void build(int node, int begin, int end, const vector<int> &A) {
if (end - begin == 1) {
m_data[node] = Node{A[begin], 0, A[begin]};
return;
}
int mid = (begin + end) / 2;
build(node * 2, begin, mid, A);
build(node * 2 + 1, mid, end, A);
m_data[node] = Node{max(m_data[node * 2].max, m_data[node * 2 + 1].max), 0, max(m_data[node * 2].best, m_data[node * 2 + 1].best)};
}
void update(int node, int begin, int end, int from, int to, int add) {
if (from <= begin && end <= to) {
m_data[node].maxadd = max(m_data[node].maxadd, add);
m_data[node].best = max(m_data[node].best, m_data[node].maxadd + m_data[node].max);
return;
}
int mid = (begin + end) / 2;
if (from < mid)
update(node * 2, begin, mid, from, to, add);
if (mid < to)
update(node * 2 + 1, mid, end, from, to, add);
m_data[node].best = max({m_data[node].best, m_data[node * 2].best, m_data[node * 2 + 1].best});
}
int query(int node, int begin, int end, int from, int to, int maxadd) {
maxadd = max(maxadd, m_data[node].maxadd);
if (from <= begin && end <= to)
return max(m_data[node].best, m_data[node].max + maxadd);
int mid = (begin + end) / 2;
int answer = 0;
if (from < mid)
answer = max(answer, query(node * 2, begin, mid, from, to, maxadd));
if (mid < to)
answer = max(answer, query(node * 2 + 1, mid, end, from, to, maxadd));
return answer;
}
int m_size;
vector<Node> m_data;
};
int main() {
ios::sync_with_stdio(false);
int N; cin >> N;
vector<int> A(N);
for (int i = 0; i < N; ++i) {
cin >> A[i];
}
vector< vector<int> > mids(N);
vector<int> stack;
for (int i = 0; i < N; ++i) {
while (!stack.empty() && A[stack.back()] <= A[i]) {
mids[stack.back()].push_back(i);
stack.pop_back();
}
if (!stack.empty())
mids[stack.back()].push_back(i);
stack.push_back(i);
}
int Q; cin >> Q;
vector< vector< pair<int, int> > > queries(N);
for (int i = 0; i < Q; ++i) {
int l, r; cin >> l >> r;
queries[l - 1].emplace_back(r, i);
}
SegmentTree S(A);
vector<int> answer(Q, 0);
for (int i = N - 1; i >= 0; --i) {
for (auto &mid : mids[i]) {
int from = 2 * mid - i;
if (from < N)
S.update(from, N, A[i] + A[mid]);
}
for (auto &[r, index] : queries[i])
answer[index] = S.query(i, r);
}
for (int i = 0; i < Q; ++i)
cout << answer[i] << "\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... |