답안 #630184

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
630184 2022-08-15T21:39:44 Z abeker 송신탑 (IOI22_towers) C++17
14 / 100
1930 ms 60232 KB
#include <bits/stdc++.h>
#include "towers.h"
using namespace std;

const int INF = INT_MAX;

class RMQ {
  int offset;
  vector <int> tour;
public:
  RMQ(vector <int> vals) {
    for (offset = 1; offset < vals.size(); offset *= 2);
    tour.resize(2 * offset);
    for (int i = 0; i < offset; i++)
      tour[i + offset] = i < vals.size() ? vals[i] : INF;
    for (int i = offset - 1; i; i--)
      tour[i] = min(tour[2 * i], tour[2 * i + 1]);
  }
  RMQ() {}
  int query(int x, int lo, int hi, int from, int to) const {
    if (lo >= to || hi <= from)
      return INF;
    if (lo >= from && hi <= to)
      return tour[x];
    int mid = (lo + hi) / 2;
    return min(query(2 * x, lo, mid, from, to), query(2 * x + 1, mid, hi, from, to));
  }
  int query(int from, int to) const {
    return query(1, 0, offset, from, to);
  }
};

class Orthogonal {
  int offset;
  vector <vector <int>> tour;
public:
  Orthogonal(vector <int> vals) {
    for (offset = 1; offset < vals.size(); offset *= 2);
    tour.resize(2 * offset);
    for (int i = 1; i < vals.size(); i++)
      tour[i + offset].push_back(vals[i]);
    for (int i = offset - 1; i; i--) {
      tour[i].resize(tour[2 * i].size() + tour[2 * i + 1].size());
      merge(tour[2 * i].begin(), tour[2 * i].end(), tour[2 * i + 1].begin(), tour[2 * i + 1].end(), tour[i].begin());
    }
  }
  Orthogonal() {}
  int query(int x, int lo, int hi, int from, int to, int val) {
    if (lo >= to || hi <= from)
      return 0;
    if (lo >= from && hi <= to)
      return lower_bound(tour[x].begin(), tour[x].end(), val) - tour[x].begin();
    int mid = (lo + hi) / 2;
    return query(2 * x, lo, mid, from, to, val) + query(2 * x + 1, mid, hi, from, to, val);
  }
  int query(int from, int to, int val) {
    return query(1, 0, offset, from, to, val);
  }
};

int N, lg;
vector <int> H;
vector <int> lb, ub;
vector <vector <int>> lft, rig;
Orthogonal count_lb, count_ub;
RMQ mini;

void init(int n, vector <int> h) {
  N = n;
  H.resize(N + 2);
  H[0] = H[N + 1] = INF;
  for (int i = 1; i <= N; i++)
    H[i] = h[i - 1];
  while (1 << lg < N)
    lg++;
  lft.resize(N + 2, vector <int> (lg + 1));
  rig.resize(N + 2, vector <int> (lg + 1));
  stack <int> s;
  s.push(0);
  for (int i = 1; i <= N; i++) {
    while (H[s.top()] < H[i])
      s.pop();
    lft[i][0] = s.top();
    s.push(i);
  }
  s = stack <int> ();
  s.push(N + 1);
  for (int i = N; i; i--) {
    while (H[s.top()] < H[i])
      s.pop();
    rig[i][0] = s.top();
    s.push(i);
  }
  rig[N + 1] = vector <int> (lg + 1, N + 1);
  for (int j = 1; j <= lg; j++)
    for (int i = 1; i <= N; i++) {
      lft[i][j] = lft[lft[i][j - 1]][j - 1];
      rig[i][j] = rig[rig[i][j - 1]][j - 1];
    }
  mini = RMQ(H);
  lb.resize(N + 1);
  ub.resize(N + 1);
  for (int i = 1; i <= N; i++) {
    int tmp = mini.query(lft[i][0] + 1, rig[i][0]);
    lb[i] = H[i] - tmp;
    ub[i] = min(H[lft[i][0]], H[rig[i][0]]) - tmp;
  }
  count_lb = Orthogonal(lb);
  count_ub = Orthogonal(ub);
}

int jump(int x, int k, const vector <vector <int>> &anc) {
  for (int i = 0; i <= lg; i++)
    if (k >> i & 1)
      x = anc[x][i];
  return x;
}

int max_towers(int l, int r, int d) {
  l += 1;
  r += 1;
  int smaller_lb = count_lb.query(l, r + 1, d);
  int smaller_ub = count_ub.query(l, r + 1, d);
  int lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(l, mid, rig);
    if (rig[node][0] <= r && lb[node] < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_lb -= lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(r, mid, lft);
    if (lft[node][0] >= l && lb[node] < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_lb -= lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(l, mid, rig);
    if (rig[node][0] <= r && H[node] - mini.query(l, rig[node][0]) < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_lb += lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(r, mid, lft);
    if (lft[node][0] >= l && H[node] - mini.query(lft[node][0] + 1, r + 1) < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_lb += lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(l, mid, rig);
    if (rig[node][0] <= r && ub[node] < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_ub -= lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(r, mid, lft);
    if (lft[node][0] >= l && ub[node] < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_ub -= lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(l, mid, rig);
    if (rig[node][0] <= r && H[rig[node][0]] - mini.query(l, rig[node][0]) < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_ub += lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(r, mid, lft);
    if (lft[node][0] >= l && H[lft[node][0]] - mini.query(lft[node][0] + 1, r + 1) < d)
      lo = mid + 1;
    else
      hi = mid;
  }
  smaller_ub += lo;
  lo = 0, hi = lg;
  while (lo < hi) {
    int mid = (lo + hi) / 2;
    int node = jump(l, mid, rig);
    if (rig[node][0] <= r)
      lo = mid + 1;
    else
      hi = mid;
  }
  int arg_max = jump(l, lo, rig);
  smaller_lb -= lb[arg_max] < d;
  smaller_lb += H[arg_max] - mini.query(l, r + 1) < d;
  smaller_ub -= ub[arg_max] < d;
  return smaller_lb - smaller_ub;
}

Compilation message

towers.cpp: In constructor 'RMQ::RMQ(std::vector<int>)':
towers.cpp:12:29: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   12 |     for (offset = 1; offset < vals.size(); offset *= 2);
      |                      ~~~~~~~^~~~~~~~~~~~~
towers.cpp:15:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   15 |       tour[i + offset] = i < vals.size() ? vals[i] : INF;
      |                          ~~^~~~~~~~~~~~~
towers.cpp: In constructor 'Orthogonal::Orthogonal(std::vector<int>)':
towers.cpp:38:29: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   38 |     for (offset = 1; offset < vals.size(); offset *= 2);
      |                      ~~~~~~~^~~~~~~~~~~~~
towers.cpp:40:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   40 |     for (int i = 1; i < vals.size(); i++)
      |                     ~~^~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 788 ms 34232 KB 5th lines differ - on the 1st token, expected: '1', found: '2'
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 464 KB Output is correct
2 Correct 2 ms 1232 KB Output is correct
3 Correct 2 ms 1232 KB Output is correct
4 Correct 2 ms 1232 KB Output is correct
5 Correct 2 ms 1232 KB Output is correct
6 Correct 2 ms 1232 KB Output is correct
7 Correct 2 ms 1232 KB Output is correct
8 Correct 2 ms 1232 KB Output is correct
9 Incorrect 2 ms 1232 KB 1st lines differ - on the 1st token, expected: '1', found: '0'
10 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 464 KB Output is correct
2 Correct 2 ms 1232 KB Output is correct
3 Correct 2 ms 1232 KB Output is correct
4 Correct 2 ms 1232 KB Output is correct
5 Correct 2 ms 1232 KB Output is correct
6 Correct 2 ms 1232 KB Output is correct
7 Correct 2 ms 1232 KB Output is correct
8 Correct 2 ms 1232 KB Output is correct
9 Incorrect 2 ms 1232 KB 1st lines differ - on the 1st token, expected: '1', found: '0'
10 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1415 ms 59424 KB Output is correct
2 Correct 1910 ms 59696 KB Output is correct
3 Correct 1890 ms 59796 KB Output is correct
4 Correct 1836 ms 59964 KB Output is correct
5 Correct 1773 ms 59820 KB Output is correct
6 Correct 1930 ms 59796 KB Output is correct
7 Correct 1897 ms 59836 KB Output is correct
8 Correct 1595 ms 60116 KB Output is correct
9 Correct 1549 ms 59780 KB Output is correct
10 Correct 1633 ms 60088 KB Output is correct
11 Correct 1684 ms 59712 KB Output is correct
12 Correct 1386 ms 60224 KB Output is correct
13 Correct 1608 ms 59840 KB Output is correct
14 Correct 0 ms 208 KB Output is correct
15 Correct 2 ms 1232 KB Output is correct
16 Correct 2 ms 1232 KB Output is correct
17 Correct 114 ms 59788 KB Output is correct
18 Correct 114 ms 59800 KB Output is correct
19 Correct 114 ms 59816 KB Output is correct
20 Correct 105 ms 59724 KB Output is correct
21 Correct 104 ms 60232 KB Output is correct
22 Correct 122 ms 59840 KB Output is correct
23 Correct 112 ms 59700 KB Output is correct
24 Correct 112 ms 59824 KB Output is correct
25 Correct 104 ms 59844 KB Output is correct
26 Correct 107 ms 59944 KB Output is correct
27 Correct 2 ms 1232 KB Output is correct
28 Correct 2 ms 1232 KB Output is correct
29 Correct 2 ms 1232 KB Output is correct
30 Correct 2 ms 1236 KB Output is correct
31 Correct 2 ms 1232 KB Output is correct
32 Correct 2 ms 1232 KB Output is correct
33 Correct 2 ms 1232 KB Output is correct
34 Correct 2 ms 1232 KB Output is correct
35 Correct 2 ms 1232 KB Output is correct
36 Correct 2 ms 1232 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 422 ms 14284 KB Output is correct
2 Correct 1633 ms 59740 KB Output is correct
3 Correct 1464 ms 59820 KB Output is correct
4 Correct 1530 ms 59728 KB Output is correct
5 Correct 1287 ms 59792 KB Output is correct
6 Correct 1657 ms 59716 KB Output is correct
7 Correct 1667 ms 59796 KB Output is correct
8 Incorrect 1222 ms 60112 KB 1st lines differ - on the 1st token, expected: '1', found: '2'
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 464 KB Output is correct
2 Correct 2 ms 1232 KB Output is correct
3 Correct 2 ms 1232 KB Output is correct
4 Correct 2 ms 1232 KB Output is correct
5 Correct 2 ms 1232 KB Output is correct
6 Correct 2 ms 1232 KB Output is correct
7 Correct 2 ms 1232 KB Output is correct
8 Correct 2 ms 1232 KB Output is correct
9 Incorrect 2 ms 1232 KB 1st lines differ - on the 1st token, expected: '1', found: '0'
10 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 788 ms 34232 KB 5th lines differ - on the 1st token, expected: '1', found: '2'
2 Halted 0 ms 0 KB -