Submission #1264564

#TimeUsernameProblemLanguageResultExecution timeMemory
1264564nguyenphucanhkhoi3단 점프 (JOI19_jumps)C++20
100 / 100
657 ms53924 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long const int MAXN = 1e6 + 26; const ll INF = 1e18; int n, m, a[MAXN]; ll ans[MAXN]; vector<pair<int, int>> candidates; vector<tuple<int, int, int>> queries; struct SegmentTree { ll tree[4 * MAXN], lazy[4 * MAXN]; ll pr[4 * MAXN]; // max a[z] in segment void build(int k, int l, int r) { lazy[k] = -INF; if (l == r) { tree[k] = -INF; pr[k] = a[l]; return; } int m = (l + r) >> 1; build(2*k, l, m); build(2*k+1, m+1, r); tree[k] = max(tree[2*k], tree[2*k+1]); pr[k] = max(pr[2*k], pr[2*k+1]); } void push(int k, int l, int r) { if (lazy[k] != -INF) { tree[k] = max(tree[k], pr[k] + lazy[k]); if (l != r) { lazy[2*k] = max(lazy[2*k], lazy[k]); lazy[2*k+1] = max(lazy[2*k+1], lazy[k]); } lazy[k] = -INF; } } void update(int k, int l, int r, int u, int v, ll f) { push(k, l, r); if (l > v || r < u) return; if (l >= u && r <= v) { lazy[k] = f; push(k, l, r); return; } int m = (l + r) >> 1; update(2*k, l, m, u, v, f); update(2*k+1, m+1, r, u, v, f); tree[k] = max(tree[2*k], tree[2*k+1]); } ll query(int k, int l, int r, int u, int v) { push(k, l, r); if (l > v || r < u) return -INF; if (l >= u && r <= v) return tree[k]; int m = (l + r) >> 1; return max(query(2*k, l, m, u, v), query(2*k+1, m+1, r, u, v)); } } seg; void find_pairs() { stack<int> st; for (int j = 1; j <= n; j++) { while (!st.empty() && a[st.top()] < a[j]) { int i = st.top(); st.pop(); candidates.push_back({i, j}); } if (!st.empty()) { candidates.push_back({st.top(), j}); } st.push(j); } } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; cin >> m; for (int i = 0; i < m; i++) { int l, r; cin >> l >> r; queries.emplace_back(l, r, i); } find_pairs(); seg.build(1, 1, n); // Sort queries by l descending sort(queries.rbegin(), queries.rend()); // Sort candidates by i descending sort(candidates.rbegin(), candidates.rend()); int j = 0; for (auto [l, r, idx] : queries) { while (j < candidates.size() && candidates[j].first >= l) { int i = candidates[j].first, j_val = candidates[j].second; int z_min = 2 * j_val - i; if (z_min <= n) { seg.update(1, 1, n, z_min, n, a[i] + a[j_val]); } j++; } ans[idx] = seg.query(1, 1, n, l, r); } for (int i = 0; i < m; i++) cout << ans[i] << "\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...