Submission #1309952

#TimeUsernameProblemLanguageResultExecution timeMemory
1309952jg86Teams (IOI15_teams)C++17
100 / 100
614 ms130060 KiB
#include <bits/stdc++.h> using namespace std; struct Node { int l, r; int sum; }; static int N; static vector<int> roots; static vector<Node> seg; static size_t baseSizeAfterInit; static inline int clone_node(int from) { seg.push_back(seg[from]); return (int)seg.size() - 1; } static int update_point(int node, int l, int r, int pos) { int n = clone_node(node); if (l == r) { seg[n].sum++; return n; } int mid = (l + r) >> 1; if (pos <= mid) seg[n].l = update_point(seg[n].l, l, mid, pos); else seg[n].r = update_point(seg[n].r, mid + 1, r, pos); seg[n].sum = seg[seg[n].l].sum + seg[seg[n].r].sum; return n; } static int query_diff(int pref, int used, int l, int r, int ql, int qr) { if (qr < l || r < ql) return 0; if (ql <= l && r <= qr) return seg[pref].sum - seg[used].sum; int mid = (l + r) >> 1; return query_diff(seg[pref].l, seg[used].l, l, mid, ql, qr) + query_diff(seg[pref].r, seg[used].r, mid + 1, r, ql, qr); } static int consume_suffix(int pref, int used, int l, int r, int start, int &need) { if (need == 0 || r < start) return used; if (l >= start) { int avail = seg[pref].sum - seg[used].sum; if (avail == 0) return used; if (avail <= need) { need -= avail; return pref; } if (l == r) { int n = clone_node(used); seg[n].sum += need; need = 0; return n; } } if (l == r) return used; int mid = (l + r) >> 1; int n = clone_node(used); if (start <= mid) seg[n].l = consume_suffix(seg[pref].l, seg[used].l, l, mid, start, need); else seg[n].l = seg[used].l; seg[n].r = consume_suffix(seg[pref].r, seg[used].r, mid + 1, r, start, need); seg[n].sum = seg[seg[n].l].sum + seg[seg[n].r].sum; return n; } void init(int N_, int A[], int B[]) { N = N_; vector<pair<int,int>> students; students.reserve(N); for (int i = 0; i < N; i++) students.push_back({A[i], B[i]}); sort(students.begin(), students.end()); size_t reserveNodes = 1ull + 20ull * (size_t)N + 8000000ull; seg.clear(); seg.reserve(reserveNodes); seg.push_back({0, 0, 0}); roots.assign(N + 1, 0); int idx = 0; for (int s = 1; s <= N; s++) { int root = roots[s - 1]; while (idx < N && students[idx].first == s) { root = update_point(root, 1, N, students[idx].second); idx++; } roots[s] = root; } baseSizeAfterInit = seg.size(); } int can(int M, int K[]) { vector<int> v; v.reserve(M); long long total = 0; for (int i = 0; i < M; i++) { v.push_back(K[i]); total += K[i]; if (total > N) return 0; } sort(v.begin(), v.end()); int used = 0; for (int i = 0; i < M; ) { int s = v[i]; int cnt = 1; while (i + cnt < M && v[i + cnt] == s) cnt++; long long need_ll = 1LL * s * cnt; int need = (int)need_ll; int pref = roots[s]; int avail = query_diff(pref, used, 1, N, s, N); if (avail < need) { seg.resize(baseSizeAfterInit); return 0; } int rem = need; used = consume_suffix(pref, used, 1, N, s, rem); i += cnt; } seg.resize(baseSizeAfterInit); return 1; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...