Submission #807439

#TimeUsernameProblemLanguageResultExecution timeMemory
807439thimote75Triple Jump (JOI19_jumps)C++14
100 / 100
761 ms107932 KiB
#include <bits/stdc++.h> #define int long long using namespace std; template <typename T> string to_string (T x) { string S = "["; bool first = true; for (const auto v : x) { if (!first) S += ", "; first = false; S += to_string(v); } S += "]"; return S; } string to_string (string S) { return S; } template <typename A, typename B> string to_string (pair<A, B> p) { return "(" + to_string(p.first )+ ", " + to_string(p.second) + ")"; } void dbg_out () { cout << endl; } template <typename Head, typename... Tail> void dbg_out (Head H, Tail... T) { cout << to_string(H) << " "; dbg_out(T...); } #ifdef DEBUG # define dbg(...) { cout << "(" << #__VA_ARGS__ << "): "; dbg_out(__VA_ARGS__); } #else # define dbg(...) #endif using idata = vector<int>; using igrid = vector<idata>; template<typename T> using grid = vector<vector<T>>; using di = pair<int, int>; using vd = vector<di>; using ti = pair<di, int> ; using vt = vector<ti>; igrid opt; struct Monoid { int p = 0, q = 0, ppq = 0; Monoid () = default; Monoid (int p, int q, int ppq) : p(p), q(q), ppq(ppq) {} static Monoid merge (Monoid &left, Monoid &right) { return Monoid( max(left.p, right.p), max(left.q, right.q), max(left.p + right.q, max(left.ppq, right.ppq)) ); } }; struct SegTree { vector<Monoid> tree; int start, height, size; SegTree (int _size) { size = _size; height = ceil(log2(size)); start = 1 << height; tree.resize(start << 1); } void update (int i) { i += start; i >>= 1; while (i != 0) { tree[i] = Monoid::merge(tree[2 * i], tree[2 * i + 1]); i >>= 1; } } void modify_p (int i, int p) { tree[i + start].p = max(tree[i + start].p, p); tree[i + start].ppq = max(tree[i + start].ppq, tree[i + start].p + tree[i + start].q); update(i); } void modify_q (int i, int q) { tree[i + start].q = max(tree[i + start].q, q); tree[i + start].ppq = max(tree[i + start].ppq, tree[i + start].p + tree[i + start].q); update(i); } int query (int l, int r) { l += start; r += start; Monoid resL; Monoid resR; idata qL, qR; while (l < r) { if ((l & 1) == 1) resL = Monoid::merge(resL, tree[l]); if ((r & 1) == 0) resR = Monoid::merge(tree[r], resR); l = (l + 1) >> 1; r = (r - 1) >> 1; } if (l == r) resL = Monoid::merge(resL, tree[l]); return Monoid::merge(resL, resR).ppq; } }; signed main () { int N; cin >> N; idata A(N); for (int i = 0; i < N; i ++) cin >> A[i]; opt.resize(N); deque<int> local; for (int i = 0; i < N; i ++) { while (local.size() != 0 && A[local.front()] < A[i]) { int curr = local.front(); local.pop_front(); opt[i].push_back(curr); } if (local.size() != 0) opt[i].push_back(local.front()); local.push_front(i); } vd opt_q; for (int i = 0; i < N; i ++) { for (int a : opt[i]) { opt_q.push_back({ a, i }); } } sort(opt_q.begin(), opt_q.end()); reverse(opt_q.begin(), opt_q.end()); int Q; cin >> Q; idata answer(Q); vt queries; for (int q = 0; q < Q; q ++) { int l, r; cin >> l >> r; l --; r --; queries.push_back({ { l, r }, q }); } sort(queries.begin(), queries.end()); reverse(queries.begin(), queries.end()); int opt_q_id = 0; int query_id = 0; SegTree tree(N); for (int i = 0; i < N; i ++) tree.modify_q(i, A[i]); for (int i = N - 1; i >= 0; i --) { while (opt_q_id != opt_q.size() && opt_q[opt_q_id].first == i) { int optA = opt_q[opt_q_id].first; int optB = opt_q[opt_q_id].second; opt_q_id ++; int optC = 2 * optB - optA; if (optC > N) continue ; tree.modify_p(optC, A[optA] + A[optB]); } while (query_id != queries.size() && queries[query_id].first.first == i) { int l = queries[query_id].first.first; int r = queries[query_id].first.second; int i = queries[query_id].second; query_id ++; answer[i] = tree.query(l, r); } } for (int u : answer) cout << u << "\n"; }

Compilation message (stderr)

jumps.cpp: In function 'int main()':
jumps.cpp:163:25: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  163 |         while (opt_q_id != opt_q.size() && opt_q[opt_q_id].first == i) {
      |                ~~~~~~~~~^~~~~~~~~~~~~~~
jumps.cpp:174:25: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<std::pair<long long int, long long int>, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  174 |         while (query_id != queries.size() && queries[query_id].first.first == i) {
      |                ~~~~~~~~~^~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...