Submission #336625

#TimeUsernameProblemLanguageResultExecution timeMemory
336625KoD3단 점프 (JOI19_jumps)C++17
100 / 100
1020 ms92404 KiB
#include <bits/stdc++.h> using i32 = std::int32_t; using i64 = std::int64_t; using u32 = std::uint32_t; using u64 = std::uint64_t; using isize = std::ptrdiff_t; using usize = std::size_t; template <class T> using Vec = std::vector<T>; constexpr i32 inf32 = (u32) ~0 >> 2; constexpr i64 inf64 = (u64) ~0 >> 2; struct Mn { u32 whole, value; static Mn id() { return Mn { 0, 0 }; } Mn operator + (const Mn other) const { return Mn { std::max(whole, other.whole), std::max(value, other.value) }; } }; struct Ef { u32 add; static Ef id() { return Ef { 0 }; } Ef operator + (const Ef other) const { return Ef { std::max(add, other.add) }; } }; Mn operator + (const Mn mn, const Ef ef) { return Mn { std::max(mn.whole, mn.value + ef.add), mn.value }; } struct Segtree { struct Node { Mn mn; Ef ef; }; void fetch(const usize i) { data[i].mn = data[i * 2 + 0].mn + data[i * 2 + 1].mn; } void apply(const usize i, const Ef ef) { data[i].mn = data[i].mn + ef; data[i].ef = data[i].ef + ef; } void flush(const usize i) { apply(i * 2 + 0, data[i].ef); apply(i * 2 + 1, data[i].ef); } static usize ctzr(const usize i) { return __builtin_ctzll(i); } static usize height(const usize i) { return 64 - __builtin_clzll(i); } void pushdown(const usize i) { const auto lsb = ctzr(i); for (usize d = height(i); --d > lsb;) { flush(i >> d); } } void pullup(usize i) { i >>= ctzr(i); while (i != 1) { i >>= 1; fetch(i); } } std::vector<Node> data; Segtree(const std::vector<u32> &vec) { const auto size = vec.size(); data.resize(size * 2, Node { Mn::id(), Ef::id() }); for (usize i = 0; i < size; ++i) { data[size + i].mn.whole = vec[i]; data[size + i].mn.value = vec[i]; } for (usize i = size - 1; i > 0; --i) { fetch(i); } } void operate(usize l, usize r, const u32 x) { l += size(); r += size(); pushdown(l); pushdown(r); const auto cl = l; const auto cr = r; const auto ef = Ef { x }; while (l < r) { if (l & 1) { apply(l, ef); l += 1; } if (r & 1) { r -= 1; apply(r, ef); } l >>= 1; r >>= 1; } pullup(cl); pullup(cr); } u32 fold(usize l, usize r) { l += size(); r += size(); pushdown(l); pushdown(r); Mn mn = Mn::id(); while (l < r) { if (l & 1) { mn = mn + data[l].mn; l += 1; } if (r & 1) { r -= 1; mn = mn + data[r].mn; } l >>= 1; r >>= 1; } return mn.whole; } usize size() const { return data.size() / 2; } }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); usize N; std::cin >> N; Vec<u32> A(N); for (auto &x: A) { std::cin >> x; } std::vector<std::vector<usize>> cand(N); std::stack<usize> stack; for (usize m = 0; m < N - 1; ++m) { while (!stack.empty()) { const auto l = stack.top(); if (m + (m - l) < N) { cand[l].push_back(m); } if (A[l] > A[m]) { break; } stack.pop(); } stack.push(m); } usize Q; std::cin >> Q; std::vector<std::vector<std::pair<usize, usize>>> query(N); for (usize i = 0; i < Q; ++i) { usize l, r; std::cin >> l >> r; l -= 1; query[l].emplace_back(i, r); } Segtree seg(A); std::vector<usize> ans(Q); for (usize l = N; l --> 0;) { for (const auto m: cand[l]) { const auto r = m + (m - l); seg.operate(r, N, A[l] + A[m]); } for (const auto [i, r]: query[l]) { ans[i] = seg.fold(l + 2, r); } } for (const auto x: ans) { std::cout << x << '\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...