Submission #631079

#TimeUsernameProblemLanguageResultExecution timeMemory
631079rainboyRadio Towers (IOI22_towers)C++17
100 / 100
1632 ms22300 KiB
#include "towers.h" #include <vector> using namespace std; const int N = 100000, L = 17, N_ = 1 << L, N1 = 1 + N * (L + 1), INF = 0x3f3f3f3f; /* L = ceil(log2(N)) */ int abs_(int a) { return a > 0 ? a : -a; } int min(int a, int b) { return a < b ? a : b; } int max(int a, int b) { return a > b ? a : b; } typedef vector<int> vi; int dd[N], iq[N + 1], pq[N], cnt; int lt(int i, int j) { return dd[i] < dd[j]; } int p2(int p) { return (p *= 2) > cnt ? 0 : (p < cnt && lt(iq[p + 1], iq[p]) ? p + 1 : p); } void pq_up(int i) { int p, q, j; for (p = pq[i]; (q = p / 2) && lt(i, j = iq[q]); p = q) iq[pq[j] = p] = j; iq[pq[i] = p] = i; } void pq_dn(int i) { int p, q, j; for (p = pq[i]; (q = p2(p)) && lt(j = iq[q], i); p = q) iq[pq[j] = p] = j; iq[pq[i] = p] = i; } void pq_add(int i) { pq[i] = ++cnt, pq_up(i); } int pq_remove_first() { int i = iq[1], j = iq[cnt--]; if (j != i) pq[j] = 1, pq_dn(j); pq[i] = 0; return i; } void pq_remove(int i) { int j = iq[cnt--]; if (j != i) pq[j] = pq[i], pq_up(j), pq_dn(j); pq[i] = 0; } int st[N_ * 2], n_; int query(int l, int r) { int x = INF; for (l += n_, r += n_; l <= r; l >>= 1, r >>= 1) { if ((l & 1) == 1) x = min(x, st[l++]); if ((r & 1) == 0) x = min(x, st[r--]); } return x; } int kk[N1], ll[N1], rr[N1], mn[N1], mx[N1], _ = 1; int update_(int t, int l, int r, int i) { int t_ = _++; ll[t_] = ll[t], rr[t_] = rr[t], kk[t_] = kk[t] + 1, mn[t_] = min(mn[t], i), mx[t_] = max(mx[t], i); if (r - l > 1) { int m = (l + r) / 2; if (i < m) ll[t_] = update_(ll[t], l, m, i); else rr[t_] = update_(rr[t], m, r, i); } return t_; } int mn_, mx_, k_; void query_(int t, int l, int r, int ql, int qr) { if (t == 0 || qr <= l || r <= ql) return; if (ql <= l && r <= qr) { mn_ = min(mn_, mn[t]), mx_ = max(mx_, mx[t]), k_ += kk[t]; return; } int m = (l + r) / 2; query_(ll[t], l, m, ql, qr), query_(rr[t], m, r, ql, qr); } int aa[N], ii[N], tt[N + 1], pp[N], qq[N], n, k; void init(int n1, vi aa_) { n = n1; for (int i = 0; i < n; i++) aa[i] = aa_[i]; k = 0; ii[k++] = 0; for (int i = 1; i < n; i++) if (k % 2 != 0) { if (aa[ii[k - 1]] > aa[i]) ii[k - 1] = i; else ii[k++] = i; } else { if (aa[ii[k - 1]] < aa[i]) ii[k - 1] = i; else ii[k++] = i; } if (k % 2 == 0) k--; for (int h = 0; h < k; h++) pp[ii[h]] = h == 0 ? -1 : ii[h - 1], qq[ii[h]] = h + 1 == k ? n : ii[h + 1]; for (int h = 0; h + 1 < k; h++) dd[ii[h]] = abs_(aa[ii[h + 1]] - aa[ii[h]]), pq_add(ii[h]); mn[0] = INF, mx[0] = -1; k = 0; while (cnt) { int i = pq_remove_first(), j = qq[i], tmp; if (pp[i] == -1) { pq_remove(j); pp[qq[j]] = -1; } else if (qq[j] == n) { pq_remove(pp[i]); qq[pp[i]] = n; } else { pq_remove(pp[i]), pq_remove(j); qq[pp[i]] = qq[j], pp[qq[j]] = pp[i]; dd[pp[i]] = abs_(aa[qq[j]] - aa[pp[i]]), pq_add(pp[i]); } if (aa[i] < aa[j]) { tmp = i, i = j, j = tmp; dd[i] = dd[j]; } ii[k++] = i; } for (int h = k - 1; h >= 0; h--) tt[h] = update_(tt[h + 1], 0, n, ii[h]); n_ = 1; while (n_ < n) n_ <<= 1; for (int i = 0; i < n; i++) st[n_ + i] = aa[i]; for (int i = n_ - 1; i > 0; i--) st[i] = min(st[i << 1 | 0], st[i << 1 | 1]); } int max_towers(int l, int r, int d) { int lower = -1, upper = k; while (upper - lower > 1) { int h = (lower + upper) / 2; if (dd[ii[h]] < d) lower = h; else upper = h; } mn_ = INF, mx_ = -1, k_ = 0; query_(tt[upper], 0, n, l, r); if (k_ == 0) return 1; else if (k_ == 1) return aa[mn_] - query(l, mn_) >= d && aa[mx_] - query(mx_, r) >= d ? 2 : 1; else return k_ - (aa[mn_] - query(l, mn_) >= d ? 0 : 1) - (aa[mx_] - query(mx_, r) >= d ? 0 : 1) + 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...