제출 #629873

#제출 시각아이디문제언어결과실행 시간메모리
629873abeker송신탑 (IOI22_towers)C++17
40 / 100
4019 ms17416 KiB
#include <bits/stdc++.h>
#include "towers.h"
using namespace std;

const int INF = 2e9;

struct Node {
  int mini, arg_max;
};

class Tournament {
  int n, offset;
  vector <int> vals;
  vector <Node> tour;
public:
  Node merge(Node lhs, Node rhs) const {
    return {min(lhs.mini, rhs.mini), vals[lhs.arg_max] > vals[rhs.arg_max] ? lhs.arg_max : rhs.arg_max};
  }
  Tournament(int n, vector <int> _vals) : n(n), vals(_vals) {
    vals.push_back(0);
    for (offset = 1; offset <= n; offset *= 2);
    tour.resize(2 * offset);
    vals.resize(offset);
    for (int i = 0; i < offset; i++)
      tour[i + offset] = {vals[i], i};
    for (int i = offset - 1; i; i--)
      tour[i] = merge(tour[2 * i], tour[2 * i + 1]);
  }
  Tournament() {}
  Node query(int x, int lo, int hi, int from, int to) const {
    if (lo >= to || hi <= from)
      return {INF, n};
    if (lo >= from && hi <= to)
      return tour[x];
    int mid = (lo + hi) / 2;
    return merge(query(2 * x, lo, mid, from, to), query(2 * x + 1, mid, hi, from, to));
  }
  Node query(int from, int to) const {
    return query(1, 0, offset, from, to);
  }
  int get(int x) const {
    return vals[x];
  }
};

int N;
Tournament solver;
vector <int> lbs, ubs;

int build_tree(int lo, int hi, int prev) {
  if (lo >= hi)
    return -INF;
  Node tmp = solver.query(lo, hi);
  int mid = tmp.arg_max;
  int maks = solver.get(mid);
  int res = prev - tmp.mini;
  lbs.push_back(max(build_tree(lo, mid, maks), build_tree(mid + 1, hi, maks)));
  ubs.push_back(res);
  return res;
}

void init(int n, vector <int> h) {
  N = n;
  solver = Tournament(n, h);
  build_tree(0, n, INF);
  sort(lbs.begin(), lbs.end());
  sort(ubs.begin(), ubs.end());
}

int solve(int lo, int hi, int ub, int diff) {
  if (lo >= hi)
    return 0;
  Node tmp = solver.query(lo, hi);
  if (tmp.mini > ub)
    return 0;
  int mid = tmp.arg_max;
  int maks = solver.get(mid);
  return max(solve(lo, mid, maks - diff, diff) + solve(mid + 1, hi, maks - diff, diff), 1);
}

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

int max_towers(int l, int r, int d) {
  if (l == 0 && r == N - 1)
    return get_smaller(lbs, d) - get_smaller(ubs, d);
  return solve(l, r + 1, INF, d);
}
#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...