제출 #155966

#제출 시각아이디문제언어결과실행 시간메모리
155966faremy3단 점프 (JOI19_jumps)C++14
100 / 100
1831 ms90064 KiB
#include <iostream> #include <algorithm> #include <stack> #include <vector> #include <utility> class Interval { int left, right; public: Interval(int l, int r) : left(l), right(r) {} bool IsIncludedIn(const Interval &other) const { return (other.left <= left && right <= other.right); } bool IsDisjointFrom(const Interval &other) const { return (other.right <= left || right <= other.left); } Interval Left() const { return Interval(left, (left + right) / 2); } Interval Right() const { return Interval((left + right) / 2, right); } }; const int MAXN = 5e5; const int LEAVES = 1 << 19; const int TSIZE = LEAVES << 1; const Interval ROOTCOVER = { 0, LEAVES }; int firmness[MAXN]; std::stack<int> useful; std::vector<std::pair<int, int>> seg[MAXN]; std::vector<std::pair<int, int>> query[MAXN]; int maxFirm[TSIZE]; int bestScore[TSIZE], lazy[TSIZE]; int answer[MAXN]; void createusefulsegments(int positions) { for (int iPos = 0; iPos < positions; iPos++) { while (!useful.empty() && firmness[useful.top()] < firmness[iPos]) { seg[useful.top()].emplace_back(2 * iPos - useful.top(), firmness[iPos] + firmness[useful.top()]); useful.pop(); } if (!useful.empty()) seg[useful.top()].emplace_back(2 * iPos - useful.top(), firmness[iPos] + firmness[useful.top()]); useful.emplace(iPos); } } void setup(int positions) { for (int iPos = 0; iPos < positions; iPos++) maxFirm[iPos + LEAVES] = firmness[iPos]; for (int iNode = LEAVES - 1; iNode > 0; iNode--) maxFirm[iNode] = std::max(maxFirm[iNode * 2], maxFirm[iNode * 2 + 1]); } void push(int node) { bestScore[node] = std::max(bestScore[node], maxFirm[node] + lazy[node]); if (node < LEAVES) { lazy[node * 2] = std::max(lazy[node * 2], lazy[node]); lazy[node * 2 + 1] = std::max(lazy[node * 2 + 1], lazy[node]); } } void update(int node, Interval covered, Interval requested, int value) { push(node); if (covered.IsIncludedIn(requested)) { lazy[node] = std::max(lazy[node], value); push(node); } else if (!covered.IsDisjointFrom(requested)) { update(node * 2, covered.Left(), requested, value); update(node * 2 + 1, covered.Right(), requested, value); bestScore[node] = std::max(bestScore[node], std::max(bestScore[node * 2], bestScore[node * 2 + 1])); } } int request(int node, Interval covered, Interval requested) { push(node); if (covered.IsIncludedIn(requested)) return bestScore[node]; if (covered.IsDisjointFrom(requested)) return 0; return std::max(request(node * 2, covered.Left(), requested), request(node * 2 + 1, covered.Right(), requested)); } int main() { std::ios::sync_with_stdio(false); std::cout.tie(nullptr); std::cin.tie(nullptr); int positions; std::cin >> positions; for (int iPos = 0; iPos < positions; iPos++) std::cin >> firmness[iPos]; createusefulsegments(positions); setup(positions); int queries; std::cin >> queries; for (int iQuery = 0; iQuery < queries; iQuery++) { int left, right; std::cin >> left >> right; query[left - 1].emplace_back(iQuery, right); } for (int iPos = positions - 1; iPos > -1; iPos--) { for (std::pair<int, int> &add : seg[iPos]) if (add.first < positions) update(1, ROOTCOVER, Interval(add.first, positions), add.second); for (std::pair<int, int> &ask : query[iPos]) answer[ask.first] = request(1, ROOTCOVER, Interval(iPos, ask.second)); } for (int iQuery = 0; iQuery < queries; iQuery++) std::cout << answer[iQuery] << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...