Submission #1090974

#TimeUsernameProblemLanguageResultExecution timeMemory
1090974fryingducFinancial Report (JOI21_financial)C++17
100 / 100
1563 ms32944 KiB
#include "bits/stdc++.h" using namespace std; #ifdef duc_debug #include "bits/debug.h" #else #define debug(...) #endif const int maxn = 3e5 + 5; int n, a[maxn], f[maxn]; int fake_a[maxn]; int d; int ord[maxn]; set<int> s; struct segment_tree { int n; vector<int> tree; segment_tree() {} segment_tree(int n) : n(n), tree(n * 4 + 6) {} void update(int ind, int l, int r, int pos, int val) { if(l == r) { tree[ind] = val; return; } int mid = (l + r) >> 1; if(pos <= mid) { update(ind << 1, l, mid, pos, val); } else { update(ind << 1 | 1, mid + 1, r, pos, val); } tree[ind] = max(tree[ind << 1], tree[ind << 1 | 1]); } int get(int ind, int l, int r, int x, int y) { if(l > y || r < x) return 0; if(x <=l and r <= y) { return tree[ind]; } int mid = (l + r) >> 1; return max(get(ind << 1, l, mid, x, y), get(ind << 1 | 1, mid + 1, r, x, y)); } void update(int pos, int val) { update(1, 1, n, pos, val); } int get(int x, int y) { if(x > y) return 0; return get(1, 1, n, x, y); } } st, st_upd; void upd(int pos) { auto it = s.lower_bound(pos); if(it != s.end()) { st_upd.update(*it, *it - pos); } if(it != s.begin()) { it--; st_upd.update(pos, pos - *it); } s.insert(pos); } void erase(int pos) { auto it = s.lower_bound(pos); int l = 0, r = 0; if(next(it) != s.end()) { r = *next(it); } if(prev(it) != s.end()) { l = *prev(it); } if(r) { if(l) st_upd.update(r, r - l); else st_upd.update(r, 0); } if(l) st_upd.update(pos, pos - l); else st_upd.update(pos, 0); s.erase(pos); } void solve() { cin >> n >> d; vector<int> vec; for(int i = 1; i <= n; ++i) { cin >> a[i]; vec.push_back(a[i]); } sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()), vec.end()); for(int i = 1; i <= n; ++i) { fake_a[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + 1; ord[i] = i; } sort(ord + 1, ord + n + 1, [](const int &x, const int &y) -> bool { return fake_a[x] < fake_a[y]; }); st = segment_tree(n); st_upd = segment_tree(n); // for(int i = 1; i <= n; ++i) { // st_upd.update(i, 0); // } for(int i = 1; i <= n; ++i) { int cur = 0; while(i + cur <= n and fake_a[ord[i]] == fake_a[ord[i + cur]]) { ++cur; } for(int j = i; j < i + cur; ++j) { f[ord[j]] = 1; upd(ord[j]); int l = 1, r = ord[j], fur = 1; while(l <= r) { int mid = (l + r) >> 1; debug(ord[j], mid, st_upd.get(mid, ord[j])); if(st_upd.get(mid, ord[j]) > d) { fur = mid; l = mid + 1; } else { r = mid - 1; } } erase(ord[j]); if(fur) f[ord[j]] = st.get(fur, ord[j]) + 1; // debug(ord[j], f[ord[j]], fur); } for(int j = i; j < i + cur; ++j) { upd(ord[j]); st.update(ord[j], f[ord[j]]); } i = i + cur - 1; } cout << *max_element(f + 1, f + n + 1); } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); solve(); 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...