Submission #1237711

#TimeUsernameProblemLanguageResultExecution timeMemory
1237711t_hollFish 3 (JOI24_fish3)C++20
100 / 100
742 ms101224 KiB
#include <bits/stdc++.h> #define int long long #define MULTITEST false using namespace std; struct monoid { int sum = 0; int size = 1; int left = 0; int right = 0; }; struct operation { int delta = 0; }; monoid merge (monoid &a, monoid &b) { return { a.sum + b.sum, a.size + b.size, a.left, b.right }; } operation chain (operation &a, operation &b) { return { a.delta + b.delta }; } monoid apply (monoid &a, operation &b) { return { a.sum + b.delta * a.size, a.size, a.left, a.right }; } struct SegTree { vector<monoid> tree; vector<operation> ops; int size, start, height; SegTree (int _size) { size = _size; height = ceil(log2(size)); start = 1 << height; tree.resize(start << 1, { 0, 1 }); ops.resize(start << 1); for (int i = start; i < tree.size(); i ++) { tree[i] = {0, 1, i - start, i - start}; } for (int i = start - 1; i > 0; i --) tree[i] = merge(tree[2 * i], tree[2 * i + 1]); } void propagate (int node) { tree[node] = apply(tree[node], ops[node]); if (node < start) { ops[2 * node] = chain(ops[2 * node], ops[node]); ops[2 * node + 1] = chain(ops[2 * node + 1], ops[node]); } ops[node] = { 0 }; } void update (int node, int ql, int qr, operation op) { propagate(node); if (qr < tree[node].left || tree[node].right < ql) return ; if (ql <= tree[node].left && tree[node].right <= qr) { ops[node] = chain(ops[node], op); propagate(node); return ; } update(2 * node, ql, qr, op); update(2 * node + 1, ql, qr, op); tree[node] = merge(tree[2 * node], tree[2 * node + 1]); } void add (int ql, int qr, int del) { update(1, ql, qr, { del }); } int sum (int ql, int qr, int node = 1) { propagate(node); if (qr < tree[node].left || tree[node].right < ql) return 0; if (ql <= tree[node].left && tree[node].right <= qr) { return tree[node].sum; } return sum(ql, qr, 2 * node) + sum(ql, qr, 2 * node + 1); } void show_tree () { for (int i = 1; i < tree.size(); i ++) { cout << tree[i].sum << "+(" << ops[i].delta << ")[" << tree[i].left << ";" << tree[i].right << "](" << tree[i].size << ") "; } cout << endl; } }; struct query { int l, r; int id; bool operator< (const query &other) const { return r < other.r; } }; void solve () { int N; cin >> N; int D; cin >> D; vector<int> A(N); for (int & a : A) cin >> a; int Q; cin >> Q; vector<query> queries; for (int i = 0; i < Q; i ++) { int l, r; cin >> l >> r; queries.push_back({ l - 1, r - 1, i }); } sort(queries.rbegin(), queries.rend()); vector<int> answers(Q, -1); vector<int> breaks; SegTree value_tree (N); SegTree cost_tree (N); for (int i = 0; i < N; i ++) { value_tree.add(i, i, A[i]); } for (int r = 0; r < N; r ++) { breaks.push_back(r); while (breaks.size() >= 2) { int bp = breaks[breaks.size() - 2]; int bm = breaks.back() - 1; int vm = value_tree.sum(bm, bm); int vl = value_tree.sum(bm + 1, bm + 1); int delta = vm - vl; if (delta <= - D) break ; int cnt = (delta + D - 1) / D; value_tree.add(bp, bm, - cnt * D); cost_tree .add(bp, bm, cnt); breaks.pop_back(); } while (queries.size() != 0 && queries.back().r == r) { query q = queries.back(); queries.pop_back(); if (value_tree.sum(q.l, q.l) >= 0) { answers[q.id] = cost_tree.sum(q.l, q.r); } } } for (int u : answers) cout << u << "\n"; } signed main () { ios_base::sync_with_stdio(false); cin.tie(NULL); int T = 1; if (MULTITEST) cin >> T; for (int t = 0; t < T; t ++) solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...