Submission #755910

#TimeUsernameProblemLanguageResultExecution timeMemory
755910MilosMilutinovic송신탑 (IOI22_towers)C++17
0 / 100
4075 ms19796 KiB
#include "towers.h" #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; vector<vector<int>> vec; namespace sparse { int n; vector<int> logs; vector<vector<int>> st; void build(vector<int> h) { n = (int) h.size(); logs.resize(n + 1); st.resize(n); for (int i = 0; i < n; i++) { st[i].resize(20); st[i][0] = h[i]; } for (int j = 1; j < 20; j++) for (int i = 0; i + (1 << j) <= n; i++) st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]); for (int i = 2; i <= n; i++) logs[i] = logs[i >> 1] + 1; } int query(int l, int r) { int k = logs[r - l + 1]; return max(st[l][k], st[r - (1 << k) + 1][k]); } }; void init(int n, vector<int> h) { vector<int> l_id(n), r_id(n); vector<int> stk; for (int i = 0; i < n; i++) { while (!stk.empty() && h[i] < h[stk.back()]) { stk.pop_back(); } l_id[i] = (stk.empty() ? -1 : stk.back()); stk.push_back(i); } stk.clear(); for (int i = n - 1; i >= 0; i--) { while (!stk.empty() && h[i] < h[stk.back()]) { stk.pop_back(); } r_id[i] = (stk.empty() ? -1 : stk.back()); stk.push_back(i); } sparse::build(h); vector<int> order(n); iota(order.begin(), order.end(), 0); sort(order.begin(), order.end(), [&](int i, int j) { return h[i] < h[j]; }); for (int _i = 1; _i < n; _i++) { int i = order[_i]; int d = 1e9; if (l_id[i] != -1) d = min(d, sparse::query(l_id[i], i) - h[i]); if (r_id[i] != -1) d = min(d, sparse::query(i, r_id[i]) - h[i]); // assert(d != 0); // printf("%d %d\n", i + 1, d); vec.push_back({d, i, l_id[i], r_id[i]}); } sort(vec.begin(), vec.end()); } int find_first(int x) { int l = 0, r = vec.size() - 1, p = vec.size(); while (l <= r) { int mid = l + r >> 1; if (vec[mid][0] >= x) r = mid - 1, p = mid; else l = mid + 1; } return vec.size() - p; } int get(int i) { return sparse::query(i, i); } bool taken[N]; int get_mn_idx(int l, int r) { int idx = l; for (int i = l; i <= r; i++) if (get(i) < get(idx)) idx = i; return idx; } int max_towers(int l, int r, int d) { vector<int> ids; for (auto& p : vec) if (p[0] >= d && l <= p[1] && p[1] <= r) ids.push_back(p[1]), taken[p[1]] = true; sort(ids.begin(), ids.end()); int idx = l; for (int i = l; i <= r; i++) { if (get(i) < get(idx)) { idx = i; } } function<void(int)> Try = [&](int idx) { if (taken[idx]) return; int L = l - 1, R = r + 1; int ans = ids.size(); for (int i : ids) { if (i < idx) L = max(L, i); else R = min(R, i); } bool ok = true; if (L >= l && max(get(L), get(idx)) > sparse::query(L, idx) - d) ok = false; if (R <= r && max(get(R), get(idx)) > sparse::query(idx, R) - d) ok = false; if (ok) taken[idx] = true, ids.push_back(idx); }; int first_l = l; while (first_l <= r && !taken[first_l]) first_l++; int first_r = r; while (first_r >= l && !taken[first_r]) first_r--; if (first_l > l) Try(get_mn_idx(l, first_l - 1)); if (first_r < r) Try(get_mn_idx(first_r + 1, r)); Try(get_mn_idx(l, r)); for (int i : ids) taken[i] = false; return ids.size(); } /* 7 3 10 20 60 40 50 30 70 1 5 10 2 2 100 0 6 17 */

Compilation message (stderr)

towers.cpp: In function 'int find_first(int)':
towers.cpp:70:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   70 |         int mid = l + r >> 1;
      |                   ~~^~~
towers.cpp: In lambda function:
towers.cpp:107:13: warning: unused variable 'ans' [-Wunused-variable]
  107 |         int ans = ids.size();
      |             ^~~
#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...