Submission #814906

# Submission time Handle Problem Language Result Execution time Memory
814906 2023-08-08T11:01:52 Z KoD Radio Towers (IOI22_towers) C++17
17 / 100
926 ms 76444 KB
#include "towers.h"

#include <algorithm>
#include <cassert>
#include <array>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace kod {

using std::cerr;
using std::cin;
using std::cout;
using std::endl;

using std::array;
using std::pair;
using std::string;
using std::tuple;
using std::vector;

using std::begin;
using std::end;

using ll = long long;
constexpr int inf = (1 << 30) - 1;
constexpr ll infll = (1ll << 62) - 1;

template <class F> int binary_search(int ok, int ng, const F& f) {
  while (std::abs(ok - ng) > 1) {
    const int md = (ok + ng) / 2;
    (f(md) ? ok : ng) = md;
  }
  return ok;
}

struct sparse_table {
  sparse_table() = default;

  explicit sparse_table(vector<int> a) {
    const int n = (int)a.size();
    table.push_back(std::move(a));
    for (int d = 1;; ++d) {
      const int m = n - (1 << d) + 1;
      if (m <= 0) break;
      table.emplace_back(m, -inf);
      for (int i = 0; i < m; ++i) {
        table[d][i] = std::max(table[d - 1][i], table[d - 1][i + (1 << (d - 1))]);
      }
    }
  }

  int range_max(int l, int r) {
    if (l == r) return -inf;
    const int d = 31 - __builtin_clz(r - l);
    return std::max(table[d][l], table[d][r - (1 << d)]);
  }

 private:
  vector<vector<int>> table;
};

struct Node {
  int l, r, sum;
};
vector<Node> node = {{0, 0, 0}};
int make_node(Node n) {
  node.push_back(std::move(n));
  return (int)node.size() - 1;
}
int make_leaf(int x) { return make_node({0, 0, x}); }
int make_parent(int l, int r) { return make_node({l, r, node[l].sum + node[r].sum}); }
int add(int u, int i, int x, int l, int r) {
  if (r - l == 1) return make_leaf(x);
  const int m = (l + r) / 2;
  if (i < m) return make_parent(add(node[u].l, i, x, l, m), node[u].r);
  return make_parent(node[u].l, add(node[u].r, i, x, m, r));
}
int fold(int u, int i, int j, int l, int r) {
  if (u == 0) return 0;
  if (j <= l || r <= i) return 0;
  if (i <= l && r <= j) return node[u].sum;
  const int m = (l + r) / 2;
  return fold(node[u].l, i, j, l, m) + fold(node[u].r, i, j, m, r);
}

struct segment_tree {
  struct Data {
    int min, max, up, down;
  };

  segment_tree() = default;

  explicit segment_tree(const vector<int>& H) {
    size = (int)H.size();
    data.resize(2 * size, {inf, -inf, -inf, -inf});
    for (int i = 0; i < size; ++i) data[i + size] = {H[i], H[i], -inf, -inf};
    for (int i = size - 1; i > 0; --i) data[i] = merge(data[2 * i], data[2 * i + 1]);
  }

  Data fold(int l, int r) const {
    l += size;
    r += size;
    Data ret_l = {inf, -inf, -inf, -inf};
    Data ret_r = {inf, -inf, -inf, -inf};
    while (l < r) {
      if (l & 1) ret_l = merge(ret_l, data[l++]);
      if (r & 1) ret_r = merge(data[--r], ret_r);
      l >>= 1;
      r >>= 1;
    }
    return merge(ret_l, ret_r);
  }

 private:
  int size;
  vector<Data> data;

  static Data merge(const Data& l, const Data& r) {
    return {std::min(l.min, r.min), std::max(l.max, r.max), std::max({l.up, r.up, r.max - l.min}),
            std::max({l.down, r.down, l.max - r.min})};
  }
};

int N;
vector<int> H, sortedD, nodeID;
sparse_table tableH, tableD;
segment_tree seg;

void init() {
  tableH = sparse_table(H);
  vector<int> D(N, inf), st;
  for (int i = 0; i < N; ++i) {
    while (!st.empty() && H[st.back()] >= H[i]) st.pop_back();
    if (!st.empty()) {
      int j = st.back();
      D[i] = std::min(D[i], tableH.range_max(j, i + 1) - H[i]);
    }
    st.push_back(i);
  }
  st.clear();
  for (int i = N - 1; i >= 0; --i) {
    while (!st.empty() && H[st.back()] > H[i]) st.pop_back();
    if (!st.empty()) {
      int j = st.back();
      D[i] = std::min(D[i], tableH.range_max(i, j + 1) - H[i]);
    }
    st.push_back(i);
  }
  tableD = sparse_table(D);
  vector<int> ord(N);
  std::iota(begin(ord), end(ord), 0);
  std::sort(begin(ord), end(ord), [&](int i, int j) { return D[i] < D[j]; });
  sortedD.resize(N);
  nodeID.resize(N + 1);
  for (int i = N - 1; i >= 0; --i) {
    const int k = ord[i];
    sortedD[i] = D[k];
    nodeID[i] = add(nodeID[i + 1], k, 1, 0, N);
  }
  seg = segment_tree(H);
}

int query(int L, int R, int D) {
  const int id = nodeID[std::lower_bound(begin(sortedD), end(sortedD), D) - begin(sortedD)];
  const int n = fold(id, L, R, 0, N);
  if (n == 0) {
    const int min = seg.fold(L, R).min;
    assert(false);
  }
  int s = binary_search(R, L, [&](int k) { return tableD.range_max(L, k) >= D; }) - 1;
  int t = binary_search(L, R, [&](int k) { return tableD.range_max(k, R) >= D; });
  int S = binary_search(L - 1, s, [&](int k) { return tableH.range_max(k, s) >= H[s] + D; }) + 1;
  int T = binary_search(R + 1, t, [&](int k) { return tableH.range_max(t, k) >= H[t] + D; }) - 1;
  // cerr << L << ' ' << S << ' ' << s << ' ' << t << ' ' << T << ' ' << R << endl;
  return n + (seg.fold(L, S).up >= D) + (seg.fold(T, R).down >= D);
}

}  // namespace kod

void init(int N, std::vector<int> H) {
  kod::N = N;
  kod::H = std::move(H);
  kod::init();
}

int max_towers(int L, int R, int D) { return kod::query(L, R + 1, D); }

Compilation message

towers.cpp: In function 'int kod::query(int, int, int)':
towers.cpp:176:15: warning: unused variable 'min' [-Wunused-variable]
  176 |     const int min = seg.fold(L, R).min;
      |               ^~~
# Verdict Execution time Memory Grader output
1 Runtime error 56 ms 44364 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 464 KB Output is correct
2 Correct 1 ms 912 KB Output is correct
3 Correct 1 ms 912 KB Output is correct
4 Correct 1 ms 912 KB Output is correct
5 Correct 1 ms 912 KB Output is correct
6 Correct 2 ms 912 KB Output is correct
7 Correct 2 ms 912 KB Output is correct
8 Runtime error 2 ms 1612 KB Execution killed with signal 6
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 464 KB Output is correct
2 Correct 1 ms 912 KB Output is correct
3 Correct 1 ms 912 KB Output is correct
4 Correct 1 ms 912 KB Output is correct
5 Correct 1 ms 912 KB Output is correct
6 Correct 2 ms 912 KB Output is correct
7 Correct 2 ms 912 KB Output is correct
8 Runtime error 2 ms 1612 KB Execution killed with signal 6
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 896 ms 76444 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 224 ms 9688 KB Output is correct
2 Correct 875 ms 39740 KB Output is correct
3 Correct 832 ms 39748 KB Output is correct
4 Correct 807 ms 39732 KB Output is correct
5 Correct 918 ms 39700 KB Output is correct
6 Correct 890 ms 39756 KB Output is correct
7 Correct 756 ms 39732 KB Output is correct
8 Correct 926 ms 40332 KB Output is correct
9 Correct 870 ms 40320 KB Output is correct
10 Correct 839 ms 40268 KB Output is correct
11 Correct 754 ms 40236 KB Output is correct
12 Correct 59 ms 39700 KB Output is correct
13 Correct 65 ms 39660 KB Output is correct
14 Correct 62 ms 39740 KB Output is correct
15 Correct 65 ms 40344 KB Output is correct
16 Correct 57 ms 39868 KB Output is correct
17 Correct 58 ms 39216 KB Output is correct
18 Correct 60 ms 39768 KB Output is correct
19 Correct 60 ms 39752 KB Output is correct
20 Correct 81 ms 39716 KB Output is correct
21 Correct 81 ms 39668 KB Output is correct
22 Correct 69 ms 39692 KB Output is correct
23 Correct 83 ms 39668 KB Output is correct
24 Correct 51 ms 40324 KB Output is correct
25 Correct 59 ms 40416 KB Output is correct
26 Correct 62 ms 39888 KB Output is correct
27 Correct 59 ms 40332 KB Output is correct
28 Correct 1 ms 912 KB Output is correct
29 Correct 1 ms 912 KB Output is correct
30 Correct 2 ms 912 KB Output is correct
31 Correct 1 ms 1036 KB Output is correct
32 Correct 1 ms 912 KB Output is correct
33 Correct 1 ms 592 KB Output is correct
34 Correct 2 ms 1028 KB Output is correct
35 Correct 1 ms 912 KB Output is correct
36 Correct 2 ms 912 KB Output is correct
37 Correct 1 ms 912 KB Output is correct
38 Correct 2 ms 912 KB Output is correct
39 Correct 1 ms 912 KB Output is correct
40 Correct 1 ms 912 KB Output is correct
41 Correct 1 ms 912 KB Output is correct
42 Correct 1 ms 1040 KB Output is correct
43 Correct 1 ms 912 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 464 KB Output is correct
2 Correct 1 ms 912 KB Output is correct
3 Correct 1 ms 912 KB Output is correct
4 Correct 1 ms 912 KB Output is correct
5 Correct 1 ms 912 KB Output is correct
6 Correct 2 ms 912 KB Output is correct
7 Correct 2 ms 912 KB Output is correct
8 Runtime error 2 ms 1612 KB Execution killed with signal 6
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Runtime error 56 ms 44364 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -