Submission #471170

#TimeUsernameProblemLanguageResultExecution timeMemory
471170apostoldaniel854Financial Report (JOI21_financial)C++14
100 / 100
874 ms26484 KiB
#include <bits/stdc++.h> using namespace std; struct node_info { int mx; node_info(int value = 0) { this->mx = value; } node_info operator + (node_info other) const { node_info RES; RES.mx = max(mx, other.mx); return RES; } }; class SegTree { private: vector <node_info> seg; int n; public: SegTree(int n) { seg.resize(1 + 4 * n); this->n = n; } void update_pos(int node, int lb, int rb, int pos, node_info val) { if (lb == rb) { seg[node] = val; return; } int mid = (lb + rb) / 2, lnode = node * 2, rnode = node * 2 + 1; if (pos <= mid) update_pos(lnode, lb, mid, pos, val); else update_pos(rnode, mid + 1, rb, pos, val); seg[node] = seg[lnode] + seg[rnode]; } void update_pos(int pos, node_info val) { update_pos(1, 1, n, pos, val); } node_info query_range(int node, int lb, int rb, int ql, int qr) { if (lb == ql && rb == qr) return seg[node]; int mid = (lb + rb) / 2, lnode = node * 2, rnode = node * 2 + 1; if (ql <= mid && qr <= mid) return query_range(lnode, lb, mid, ql, qr); else if (mid + 1 <= ql && mid + 1 <= qr) return query_range(rnode, mid + 1, rb, ql, qr); else return query_range(lnode, lb, mid, ql, mid) + query_range(rnode, mid + 1, rb, mid + 1, qr); } node_info query_range(int ql, int qr) { if (ql > qr) return node_info(); return query_range(1, 1, n, ql, qr); } }; const int MAX_N = 3e5; int a[1 + MAX_N]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, D; cin >> n >> D; for (int i = 1; i <= n; i++) cin >> a[i]; vector <int> order(n); iota(order.begin(), order.end(), 1); sort(order.begin(), order.end(), [&](int x, int y) { if (a[x] != a[y]) return a[x] < a[y]; return x > y; }); set <int> stk; stk.insert(0); stk.insert(n + 1); SegTree dp(n); set <int> blocked; for (int i = 1; i <= n - D; i++) blocked.insert(i); for (int i : order) { auto it = stk.lower_bound(i); int nxt = *it, prv = *prev(it); if (nxt - prv > D) { if (nxt - i <= D) { for (int j = i; j <= nxt; j++) blocked.erase(j); } if (i - prv <= D) for (int j = prv; j <= i; j++) blocked.erase(j); } it = blocked.lower_bound(i); int bound; if (it == blocked.begin()) bound = 1; else bound = *prev(it); int best = dp.query_range(bound, i).mx; dp.update_pos(i, node_info(best + 1)); stk.insert(i); } cout << dp.query_range(1, 1, n, 1, n).mx << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...