제출 #629926

#제출 시각아이디문제언어결과실행 시간메모리
629926abekerRadio Towers (IOI22_towers)C++17
40 / 100
4100 ms173036 KiB
#include <bits/stdc++.h>
#include "towers.h"
using namespace std;

typedef pair <vector <int>, vector <int>> pvv;

const int INF = 2e9 + 5;

class Tournament {
  int offset;
  vector <int> tour;
public:
  Tournament(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]);
  }
  Tournament() {}
  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);
  }
};

int N;
vector <int> H;
map <pair <int, int>, pvv> memo;

void init(int n, vector <int> h) {
  N = n;
  H = h;
}

int get_smaller(const vector <int> &v, int x) {
  return lower_bound(v.begin(), v.end(), x) - v.begin();
}

const pvv& calc(int l, int r) {
  pvv& ref = memo[{l, r}];
  if (!ref.first.empty() && !ref.second.empty())
    return ref;
  int n = r - l + 1;
  vector <int> h(n + 2);
  vector <int> lft(n + 1), rig(n + 1);
  h[0] = h[n + 1] = INF;
  for (int i = 1; i <= n; i++)
    h[i] = H[i + l - 1];
  Tournament solver(h);
  stack <int> s;
  s.push(0);
  for (int i = 1; i <= n; i++) {
    while (h[s.top()] < h[i])
      s.pop();
    lft[i] = 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] = s.top();
    s.push(i);
  }
  for (int i = 1; i <= n; i++) {
    int tmp = solver.query(lft[i] + 1, rig[i]);
    ref.first.push_back(h[i] - tmp);
    ref.second.push_back(min(h[lft[i]], h[rig[i]]) - tmp);
  }
  sort(ref.first.begin(), ref.first.end());
  sort(ref.second.begin(), ref.second.end());
  return ref;
}

int max_towers(int l, int r, int d) {
  const pvv& ref = calc(l, r);
  return get_smaller(ref.first, d) - get_smaller(ref.second, d);
}

컴파일 시 표준 에러 (stderr) 메시지

towers.cpp: In constructor 'Tournament::Tournament(std::vector<int>)':
towers.cpp:14:29: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   14 |     for (offset = 1; offset < vals.size(); offset *= 2);
      |                      ~~~~~~~^~~~~~~~~~~~~
towers.cpp:17:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   17 |       tour[i + offset] = i < vals.size() ? vals[i] : INF;
      |                          ~~^~~~~~~~~~~~~
#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...