Submission #413662

#TimeUsernameProblemLanguageResultExecution timeMemory
413662rabbitsthecatTriple Jump (JOI19_jumps)C++17
19 / 100
2238 ms524292 KiB
#include "bits/stdc++.h" using namespace std; #define ffor(n) for(int i = 0; i < n; i++) #define fffor(n) for(int j = 0; j < n; j++) #define uwu ios::sync_with_stdio(false);cin.tie(NULL); #pragma GCC optimize("Ofast") const int INF = 1e9 + 7; const long long INF2 = 1e17; struct node{ int value; node() { value = 0; } node(int _value) { value = _value; } }; struct segmenttree{ int n, n2 = 1; vector <node> tree; // CHANGE THIS node merge(node p, node q) { return max(p.value, q.value); } segmenttree(vector <node>& v) { n = v.size(); while(n2 < n) n2 *= 2; tree = vector <node>(2 * n2); for(int i = 0; i < n; i++) { tree[i + n2] = v[i]; } for(int i = n2 - 1; i >= 1; i--) { tree[i] = merge(tree[2 * i], tree[2 * i + 1]); } } void update(int pos, node value) { pos += n2 - 1; tree[pos] = value; // AND POSSIBLY THIS while(pos > 1) { pos /= 2; tree[pos] = merge(tree[2 * pos], tree[2 * pos + 1]); } } node query(int current, int a, int b, int l, int r, int node_span) { if (a <= l && r <= b) { return tree[current]; } else if (a > r || l > b) { return node(); } else { int child_span = node_span / 2; return merge(query(2 * current, a, b, l, l + child_span - 1, child_span), query(2 * current + 1, a, b, l + child_span, r, child_span)); } } node query(int a, int b) { return query(1, a, b, 1, n2, n2); } }; int main(void) { uwu int n; cin >> n; vector <long long> v(n); ffor(n) cin >> v[i]; /* * let dp[i][j] -> max answer if we start at i and end at j * we query the maximum in range (i + 1, (i + j) / 2) */ vector <node> temp(n); ffor(n) temp[i] = v[i]; segmenttree tree(temp); vector <vector <long long>> dp(n, vector <long long>(n)); for(int i = 0; i < n; i++) { for(int j = i + 2; j < n; j++) { int left = i + 1, right = (i + j) / 2; int maximum = tree.query(left + 1, right + 1).value; dp[i][j] = v[i] + v[j] + maximum; } } vector <vector <long long>> dp2(n, vector <long long>(n, -1)); auto update = [&] (int left, int right, auto&& update) -> void { if (dp2[left][right] != -1) return; if (left == right) { dp2[left][right] = 0; } else { update(left + 1, right, update); update(left, right - 1, update); dp2[left][right] = max({dp[left][right], dp2[left][right - 1], dp2[left + 1][right]}); } }; update(0, n - 1, update); int q; cin >> q; ffor(q) { int a, b; cin >> a >> b; a--; b--; cout << dp2[a][b] << '\n'; } } /* C:\Users\kenne\OneDrive\Desktop\competitive_programming\main.cpp */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...