Submission #1225697

#TimeUsernameProblemLanguageResultExecution timeMemory
1225697k12_khoiTriple Jump (JOI19_jumps)C++17
0 / 100
160 ms6300 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair<int, int> #define X first #define Y second const int N = 5e5 + 5; const ll INF = 1e18; struct Query { int L, R, id; }; int n, block_size; int a[N], max_in_block[N / 1000 + 5]; ll f[N], lazy_block[N / 1000 + 5], best_in_block[N / 1000 + 5]; vector<pii> candidate_pairs; void update_block(int pos, ll value) { int block = pos / block_size; int start = block * block_size; int end = min((block + 1) * block_size - 1, n); if (lazy_block[block] < value) { lazy_block[block] = value; best_in_block[block] = lazy_block[block] + max_in_block[block]; } if (f[pos] < value) { f[pos] = value; best_in_block[block] = max(best_in_block[block], f[pos] + a[pos]); } for (int i = start; i <= end; i++) { if (f[i] < lazy_block[block]) { f[i] = lazy_block[block]; } best_in_block[block] = max(best_in_block[block], f[i] + a[i]); } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> n; block_size = sqrt(n); for (int i = 1; i <= n; i++) { cin >> a[i]; int block_idx = i / block_size; if (a[i] > max_in_block[block_idx]) { max_in_block[block_idx] = a[i]; } } deque<int> dq; for (int i = n; i >= 1; i--) { while (!dq.empty() && a[i] >= a[dq.back()]) { candidate_pairs.push_back({i, dq.back()}); dq.pop_back(); } if (!dq.empty()) { candidate_pairs.push_back({i, dq.front()}); } dq.push_front(i); } int q; cin >> q; vector<Query> queries(q); vector<ll> ans(q, -INF); for (int i = 0; i < q; i++) { cin >> queries[i].L >> queries[i].R; queries[i].id = i; } sort(queries.begin(), queries.end(), [](const Query& a, const Query& b) { return a.L > b.L; }); for (int i = 0; i <= n; i++) { f[i] = -INF; } int num_blocks = (n + block_size - 1) / block_size; for (int i = 0; i < num_blocks; i++) { lazy_block[i] = -INF; best_in_block[i] = -INF; } sort(candidate_pairs.begin(), candidate_pairs.end(), greater<pii>()); int ptr = 0; for (const auto& query : queries) { int L = query.L, R = query.R, id = query.id; while (ptr < candidate_pairs.size() && candidate_pairs[ptr].X >= L) { int x = candidate_pairs[ptr].X; int y = candidate_pairs[ptr].Y; ll s = a[x] + a[y]; int c_min = 2 * y - x; ptr++; if (c_min > n) continue; int start_block = c_min / block_size; int end_block = num_blocks - 1; for (int block = start_block; block <= end_block; block++) { int block_start = block * block_size; int block_end = min((block + 1) * block_size - 1, n); if (c_min <= block_start) { if (s > lazy_block[block]) { lazy_block[block] = s; best_in_block[block] = max(best_in_block[block], lazy_block[block] + max_in_block[block]); } } else { for (int j = max(c_min, block_start); j <= block_end; j++) { if (s > f[j]) { f[j] = s; best_in_block[block] = max(best_in_block[block], f[j] + a[j]); } } } } } ll best = -INF; int start_pos = L + 2; if (start_pos > R) { ans[id] = -INF; continue; } int start_block = start_pos / block_size; int end_block = R / block_size; for (int block = start_block; block <= end_block; block++) { int block_start = block * block_size; int block_end = min((block + 1) * block_size - 1, n); if (block_start >= start_pos && block_end <= R) { best = max(best, best_in_block[block]); } else { for (int j = max(start_pos, block_start); j <= min(R, block_end); j++) { if (f[j] < lazy_block[block]) { f[j] = lazy_block[block]; } best = max(best, f[j] + a[j]); } } } ans[id] = best; } for (int i = 0; i < q; i++) { cout << ans[i] << '\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...