답안 #814892

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
814892 2023-08-08T10:56:55 Z KoD 송신탑 (IOI22_towers) C++17
17 / 100
1083 ms 40400 KB
#include "towers.h"

#include <algorithm>
#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) return 1;
  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); }
# 결과 실행 시간 메모리 Grader output
1 Incorrect 316 ms 22648 KB 12th lines differ - on the 1st token, expected: '2', found: '1'
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 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 2 ms 912 KB Output is correct
5 Correct 1 ms 912 KB Output is correct
6 Correct 1 ms 912 KB Output is correct
7 Correct 1 ms 912 KB Output is correct
8 Correct 1 ms 912 KB Output is correct
9 Correct 1 ms 912 KB Output is correct
10 Correct 1 ms 912 KB Output is correct
11 Correct 1 ms 912 KB Output is correct
12 Incorrect 1 ms 208 KB 1st lines differ - on the 1st token, expected: '2', found: '1'
13 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 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 2 ms 912 KB Output is correct
5 Correct 1 ms 912 KB Output is correct
6 Correct 1 ms 912 KB Output is correct
7 Correct 1 ms 912 KB Output is correct
8 Correct 1 ms 912 KB Output is correct
9 Correct 1 ms 912 KB Output is correct
10 Correct 1 ms 912 KB Output is correct
11 Correct 1 ms 912 KB Output is correct
12 Incorrect 1 ms 208 KB 1st lines differ - on the 1st token, expected: '2', found: '1'
13 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 769 ms 39484 KB Output is correct
2 Correct 996 ms 39796 KB Output is correct
3 Correct 999 ms 39708 KB Output is correct
4 Correct 1027 ms 39684 KB Output is correct
5 Correct 1083 ms 39724 KB Output is correct
6 Correct 1031 ms 39724 KB Output is correct
7 Correct 936 ms 39672 KB Output is correct
8 Correct 822 ms 40380 KB Output is correct
9 Correct 739 ms 40300 KB Output is correct
10 Correct 941 ms 40204 KB Output is correct
11 Correct 791 ms 40212 KB Output is correct
12 Incorrect 735 ms 40364 KB 170th lines differ - on the 1st token, expected: '2', found: '1'
13 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 243 ms 9664 KB Output is correct
2 Correct 761 ms 39684 KB Output is correct
3 Correct 988 ms 39728 KB Output is correct
4 Correct 995 ms 39708 KB Output is correct
5 Correct 802 ms 39692 KB Output is correct
6 Correct 752 ms 39744 KB Output is correct
7 Correct 916 ms 39660 KB Output is correct
8 Correct 809 ms 40400 KB Output is correct
9 Correct 774 ms 40364 KB Output is correct
10 Correct 760 ms 40216 KB Output is correct
11 Correct 804 ms 40236 KB Output is correct
12 Correct 62 ms 39684 KB Output is correct
13 Correct 65 ms 39756 KB Output is correct
14 Correct 67 ms 39636 KB Output is correct
15 Correct 53 ms 40300 KB Output is correct
16 Correct 55 ms 39944 KB Output is correct
17 Correct 62 ms 39180 KB Output is correct
18 Correct 65 ms 39688 KB Output is correct
19 Correct 62 ms 39688 KB Output is correct
20 Correct 60 ms 39772 KB Output is correct
21 Correct 60 ms 39652 KB Output is correct
22 Correct 61 ms 39696 KB Output is correct
23 Correct 79 ms 39672 KB Output is correct
24 Correct 51 ms 40316 KB Output is correct
25 Correct 67 ms 40396 KB Output is correct
26 Correct 50 ms 39936 KB Output is correct
27 Correct 48 ms 40364 KB Output is correct
28 Correct 1 ms 912 KB Output is correct
29 Correct 1 ms 912 KB Output is correct
30 Correct 1 ms 992 KB Output is correct
31 Correct 1 ms 912 KB Output is correct
32 Correct 2 ms 912 KB Output is correct
33 Correct 1 ms 592 KB Output is correct
34 Correct 1 ms 912 KB Output is correct
35 Correct 1 ms 912 KB Output is correct
36 Correct 1 ms 912 KB Output is correct
37 Correct 1 ms 912 KB Output is correct
38 Correct 1 ms 912 KB Output is correct
39 Correct 1 ms 912 KB Output is correct
40 Correct 1 ms 1040 KB Output is correct
41 Correct 1 ms 912 KB Output is correct
42 Correct 1 ms 912 KB Output is correct
43 Correct 1 ms 912 KB Output is correct
# 결과 실행 시간 메모리 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 2 ms 912 KB Output is correct
5 Correct 1 ms 912 KB Output is correct
6 Correct 1 ms 912 KB Output is correct
7 Correct 1 ms 912 KB Output is correct
8 Correct 1 ms 912 KB Output is correct
9 Correct 1 ms 912 KB Output is correct
10 Correct 1 ms 912 KB Output is correct
11 Correct 1 ms 912 KB Output is correct
12 Incorrect 1 ms 208 KB 1st lines differ - on the 1st token, expected: '2', found: '1'
13 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 316 ms 22648 KB 12th lines differ - on the 1st token, expected: '2', found: '1'
2 Halted 0 ms 0 KB -