제출 #479846

#제출 시각아이디문제언어결과실행 시간메모리
479846alextodoranFinancial Report (JOI21_financial)C++17
100 / 100
430 ms29668 KiB
/** ____ ____ ____ ____ ____ ||a |||t |||o |||d |||o || ||__|||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|/__\| **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N_MAX = 300000; int N, D; int A[N_MAX + 2]; struct DSUNode { int root; int l, r; }; DSUNode DSU[N_MAX + 2]; void init () { for(int u = 1; u <= N; u++) { DSU[u].root = u; DSU[u].l = u; DSU[u].r = u; } } int findRoot (int u) { if(DSU[u].root == u) return u; return DSU[u].root = findRoot(DSU[u].root); } void join (int u, int v) { u = findRoot(u); v = findRoot(v); if(u == v) return; DSU[v].l = DSU[u].l; DSU[u].root = v; } bool active[N_MAX + 2]; void activate (int u) { active[u] = true; if(active[u - 1] == true) join(u - 1, u); if(active[u + 1] == true) join(u, u + 1); } int order[N_MAX + 2]; int leftBound[N_MAX + 2]; int SGT[N_MAX * 4 + 2]; void update (int node, int l, int r, int upos, int uval) { if(l == r) { SGT[node] = uval; return; } int mid = (l + r) / 2; int lSon = node * 2, rSon = node * 2 + 1; if(upos <= mid) update(lSon, l, mid, upos, uval); if(mid + 1 <= upos) update(rSon, mid + 1, r, upos, uval); SGT[node] = max(SGT[lSon], SGT[rSon]); } void update (int upos, int uval) { update(1, 1, N, upos, uval); } int query (int node, int l, int r, int ql, int qr) { if(ql <= l && r <= qr) return SGT[node]; int mid = (l + r) / 2; int lSon = node * 2, rSon = node * 2 + 1; int answer = 0; if(ql <= mid) answer = max(answer, query(lSon, l, mid, ql, qr)); if(mid + 1 <= qr) answer = max(answer, query(rSon, mid + 1, r, ql, qr)); return answer; } int query (int ql, int qr) { if(ql > qr) return 0; return query(1, 1, N, ql, qr); } int maxRec[N_MAX + 2]; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> N >> D; for(int i = 1; i <= N; i++) cin >> A[i]; for(int k = 1; k <= N; k++) order[k] = k; { sort(order + 1, order + N + 1, [&] (const int &i, const int &j) { return make_pair(A[i], i) > make_pair(A[j], j); }); set <int> s; init(); for(int k = 1; k <= N; k++) { int i = order[k]; set <int> :: iterator it = s.upper_bound(i); if(it == s.begin()) leftBound[i] = 1; else leftBound[i] = (*prev(it) - D + 1); activate(i); int root = findRoot(i); if(DSU[root].r - DSU[root].l + 1 >= D) s.insert(DSU[root].r); } } { sort(order + 1, order + N + 1, [&] (const int &i, const int &j) { return make_pair(A[i], N - i) < make_pair(A[j], N - j); }); for(int k = 1; k <= N; k++) { int i = order[k]; maxRec[i] = query(leftBound[i], i - 1) + 1; update(i, maxRec[i]); } cout << query(1, N) << "\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...