답안 #917357

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
917357 2024-01-27T23:40:15 Z agusss 3D Histogram (COCI20_histogram) C++17
0 / 110
2 ms 604 KB
#include "vector"
#include "stack"
#include "iostream"
#include <algorithm>


using namespace std;


struct Type { int v; };

struct SegmentTree {

  struct NodeType { int l, r, min; };

  NodeType merge_nodes(NodeType a, NodeType b) {
    return { a.l, b.r, min(a.min, b.min) };
  };

  NodeType set_leaf(int i, Type a) {
    return { i, i, a.v };
  }

  vector<NodeType> tree;

  vector<Type> *array;

  int left(int index) { return (index << 1) + 1; }

  int right(int index) { return (index << 1) + 2; }

  int mid(int l, int r) { return (l + r) >> 1; }

  bool on_left(NodeType a, int i) { return i <= mid(a.l, a.r); }

  void _build(int index, int l, int r) {
    if (l == r) {
      tree[index] = set_leaf(l, (*array)[l]); 
    } else {
      _build(left(index), l, mid(l, r));
      _build(right(index), mid(l, r) + 1, r);
      tree[index] = merge_nodes(tree[left(index)], tree[right(index)]);
    }
  }

  void build(vector<Type> &A) {
    array = &A;
    tree.resize((*array).size() * 4);
    _build(0, 0, (*array).size() - 1);
  }

  int u_i;

  Type u_v;

  void _update(int index) {
    if (tree[index].l == tree[index].r) {
      tree[index] = set_leaf(u_i, u_v);
      (*array)[u_i] = u_v;
    } else {
      if (on_left(tree[index], u_i)) {
        _update(left(index));
      } else {
        _update(right(index));
      }
      tree[index] = merge_nodes(tree[left(index)], tree[right(index)]);
    }
  }

  void update(int i, Type v) {
    u_i = i;
    u_v = v;
    _update(0);
  }

  int q_l;
  
  int q_r;
  
  NodeType _query(int index) {
    if (q_l <= tree[index].l and tree[index].r <= q_r) {
      return tree[index];
    }
    if (on_left(tree[index], q_r)) {
      return _query(left(index));
    }
    if (!on_left(tree[index], q_l)) {
      return _query(right(index));
    }
    return merge_nodes(_query(left(index)), _query(right(index))); 
  }

  NodeType query(int l, int r) {
    q_l = l;
    q_r = r;
    return _query(0);
  }
};

long long largestRectangleArea(vector<int>& heights, vector<Type> &wides) {
  int n = heights.size();
  int left_smaller[n];
  int right_smaller[n];
  stack<int> s;
  int i = 0;
  while (i < n) {
    while (!s.empty() && heights[s.top()] >= heights[i]) {
      s.pop();
    }
    if (i > 0 && heights[i] == heights[i - 1]) {
      left_smaller[i] = left_smaller[i - 1];
    } else {
      left_smaller[i] = s.empty() ? -1 : s.top();
    }
    s.push(i);
    i++;
  }
  s = stack<int>();
  i = n - 1;
  while (i >= 0) {
    // TODO create test cases to WA for only >
    while (!s.empty() && heights[s.top()] >= heights[i]) {
      s.pop();
    }
    if (i + 1 < n && heights[i] == heights[i + 1]) {
      right_smaller[i] = right_smaller[i + 1];
    } else {
      right_smaller[i] = s.empty() ? n : s.top();
    }
    s.push(i);
    i--;
  }

  // 
  int left_w_smaller[n];
  int right_w_smaller[n];
  s = stack<int>();
  i = 0;
  while (i < n) {
    while (!s.empty() && wides[s.top()].v >= wides[i].v) {
      s.pop();
    }
    if (i > 0 && wides[i].v == wides[i - 1].v) {
      left_w_smaller[i] = left_w_smaller[i - 1];
    } else {
      left_w_smaller[i] = s.empty() ? -1 : s.top();
    }
    s.push(i);
    i++;
  }
  s = stack<int>();
  i = n - 1;
  while (i >= 0) {
    // TODO create test cases to WA for only >
    while (!s.empty() && wides[s.top()].v >= wides[i].v) {
      s.pop();
    }
    if (i + 1 < n && wides[i].v == wides[i + 1].v) {
      right_w_smaller[i] = right_w_smaller[i + 1];
    } else {
      right_w_smaller[i] = s.empty() ? n : s.top();
    }
    s.push(i);
    i--;
  }

  //for (int i = 0; i < n; i++) cout << left_smaller[i] << ", "; cout << "\n";
  //for (int i = 0; i < n; i++) cout << right_smaller[i] << ", "; cout << "\n";
  long long max_area = 0;
  SegmentTree st;
  st.build(wides);
  for (int i = 0; i < n; i ++) {
    long long area = (long long)heights[i] * (long long)(right_smaller[i] - left_smaller[i] - 1);
    auto [ _, __, x ] = st.query(left_smaller[i] + 1, right_smaller[i] -1);
    max_area = max(max_area, area * x);
    int l = max(left_smaller[i], left_w_smaller[i]);
    int r = min(right_smaller[i], right_w_smaller[i]);
    max_area = max(max_area, (long long)heights[i] * (long long)(r - l - 1) * (long long)wides[i].v);
  }
  return max_area;
}


int main() {

  int n, x, y;
  while(scanf("%d\n", &n) != EOF) {
    vector<int> A;
    vector<Type> B;
    vector<int> C;
    vector<Type> D;
    for (int i = 0; i < n; i++) {
      if (scanf("%d %d", &x, &y)) ;
      A.push_back(x);
      B.push_back({ y });
      C.push_back(y);
      D.push_back({ x });
    }
    printf("%lld\n", max(largestRectangleArea(A, B), largestRectangleArea(C, D)));
  }
  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 604 KB Output is correct
2 Correct 1 ms 604 KB Output is correct
3 Correct 1 ms 600 KB Output is correct
4 Incorrect 2 ms 600 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 604 KB Output is correct
2 Correct 1 ms 604 KB Output is correct
3 Correct 1 ms 600 KB Output is correct
4 Incorrect 2 ms 600 KB Output isn't correct
5 Halted 0 ms 0 KB -