Submission #499389

# Submission time Handle Problem Language Result Execution time Memory
499389 2021-12-28T10:29:19 Z daidailanlan Deda (COCI17_deda) C++17
140 / 140
146 ms 13040 KB
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
namespace math {
inline uint32_t nextPow2_32(uint32_t v) {
  if (!v) {
    return 1;
  }
  uint32_t res = 1U << (31 ^ __builtin_clz(v));
  return res == v ? res : res << 1;
}
} // namespace math
namespace ds {
template<typename V, typename InitV = V, typename Update = InitV, typename TraverseArgs = nullptr_t>
struct BaseLazyCompactSegmentTree {
  struct Node {
    V v;
    Update update;
    int lower, upper;
    inline bool isValid() const {
      return lower < upper;
    }
    inline bool isLeaf() const {
      return lower + 1 == upper;
    }
  };
  enum Traverse { NONE, LEFT, RIGHT, ALL };
  virtual inline Traverse _traverse(Node& node, int lower, int upper, TraverseArgs& args) {
    return Traverse::NONE;
  }
  virtual inline bool _hasUpdate(Node& node) = 0;
  virtual inline void _applyUpdate(const Update& update, Node& node) = 0;
  virtual inline void _clearUpdate(Node& node) = 0;
  virtual inline void _initV(InitV initV, Node& node) = 0;
  virtual inline void _mergeV(const Node& lNode, const Node& rNode, V& res) = 0;
  inline void init(vector<InitV> initVs) {
    int n = static_cast<int>((initVs).size());
    _offset = math::nextPow2_32(n);
    _offsetBit = __builtin_ctz(_offset);
    _nodes.resize(_offset << 1);
    for (int i = (0); i < (n); ++i) {
      auto& node = _nodes[_offset + i];
      node.lower = i;
      node.upper = i + 1;
      _clearUpdate(node);
      _initV(move(initVs[i]), node);
    }
    for (int i = (n); i < (_offset); ++i) {
      auto& node = _nodes[_offset + i];
      node.lower = -1;
      node.upper = -2;
    }
    for (int i = (_offset - 1); i >= (1); --i) {
      auto& node = _nodes[i];
      const auto &lNode = _nodes[i << 1], rNode = _nodes[(i << 1) | 1];
      if (lNode.upper == rNode.lower) {
        node.lower = lNode.lower;
        node.upper = rNode.upper;
        _clearUpdate(node);
        _mergeV(lNode, rNode, node.v);
      } else {
        node.lower = -1;
        node.upper = -2;
      }
    }
  }
  inline void updateRange(int lower, int upper, const Update& update) {
    lower += _offset;
    upper += _offset;
    int lowerCtz1 = __builtin_ctz(lower) + 1, upperCtz1 = __builtin_ctz(upper) + 1,
        commonCtz1 = max(lowerCtz1, upperCtz1);
    for (int i = (_offsetBit); i >= (commonCtz1); --i) {
      _push(lower >> i);
      _push((upper - 1) >> i);
    }
    for (int i = (commonCtz1 - 1); i >= (lowerCtz1); --i) {
      _push(lower >> i);
    }
    for (int i = (commonCtz1 - 1); i >= (upperCtz1); --i) {
      _push((upper - 1) >> i);
    }
    for (int l = lower, u = upper; l < u; l >>= 1, u >>= 1) {
      if (l & 1) {
        _applyUpdateWrapper(update, _nodes[l++]);
      }
      if (u & 1) {
        _applyUpdateWrapper(update, _nodes[--u]);
      }
    }
    for (int i = (lowerCtz1); i < (commonCtz1); ++i) {
      _mergeVWrapper(lower >> i);
    }
    for (int i = (upperCtz1); i < (commonCtz1); ++i) {
      _mergeVWrapper((upper - 1) >> i);
    }
    for (int i = commonCtz1; i <= _offsetBit; ++i) {
      _mergeVWrapper(lower >> i);
      _mergeVWrapper((upper - 1) >> i);
    }
  }
  inline void traverseRange(int lower, int upper, TraverseArgs& args) {
    int lower2 = lower + _offset;
    int upper2 = upper + _offset;
    int lowerCtz1 = __builtin_ctz(lower2) + 1, upperCtz1 = __builtin_ctz(upper2) + 1,
        commonCtz1 = max(lowerCtz1, upperCtz1);
    for (int i = (_offsetBit); i >= (commonCtz1); --i) {
      _push(lower2 >> i);
      _push((upper2 - 1) >> i);
    }
    for (int i = (commonCtz1 - 1); i >= (lowerCtz1); --i) {
      _push(lower2 >> i);
    }
    for (int i = (commonCtz1 - 1); i >= (upperCtz1); --i) {
      _push((upper2 - 1) >> i);
    }
    int bit = 0;
    for (int l = lower2; l < (upper2 >> bit); ++bit, l >>= 1) {
      if (l & 1) {
        _traverseWrapper(l++, lower, upper, args);
      }
    }
    for (--bit; bit >= 0; --bit) {
      int u = upper2 >> bit;
      if (u & 1) {
        _traverseWrapper(u ^ 1, lower, upper, args);
      }
    }
    for (int i = (lowerCtz1); i < (commonCtz1); ++i) {
      _mergeVWrapper(lower2 >> i);
    }
    for (int i = (upperCtz1); i < (commonCtz1); ++i) {
      _mergeVWrapper((upper2 - 1) >> i);
    }
    for (int i = commonCtz1; i <= _offsetBit; ++i) {
      _mergeVWrapper(lower2 >> i);
      _mergeVWrapper((upper2 - 1) >> i);
    }
  }
  inline void _push(int idx) {
    auto& node = _nodes[idx];
    if (!node.isValid() || node.isLeaf() || !_hasUpdate(node)) {
      return;
    }
    _applyUpdate(node.update, _nodes[idx << 1]);
    _applyUpdate(node.update, _nodes[(idx << 1) | 1]);
    _clearUpdate(node);
  }
  inline void _mergeVWrapper(int idx) {
    auto& node = _nodes[idx];
    if (node.isValid()) {
      _mergeV(_nodes[idx << 1], _nodes[(idx << 1) | 1], node.v);
    }
  }
  inline void _applyUpdateWrapper(const Update& update, Node& node) {
    if (node.isValid()) {
      _applyUpdate(update, node);
    }
  }
  inline void _traverseWrapper(int idx, int lower, int upper, TraverseArgs& args) {
    auto& node = _nodes[idx];
    Traverse traverse = _traverse(node, lower, upper, args);
    if (traverse == Traverse::NONE || node.isLeaf()) {
      return;
    }
    if (_hasUpdate(node)) {
      _applyUpdate(node.update, _nodes[idx << 1]);
      _applyUpdate(node.update, _nodes[(idx << 1) | 1]);
      _clearUpdate(node);
    }
    if (traverse != Traverse::RIGHT) {
      _traverseWrapper(idx << 1, lower, upper, args);
    }
    if (traverse != Traverse::LEFT) {
      _traverseWrapper((idx << 1) | 1, lower, upper, args);
    }
    _mergeV(_nodes[idx << 1], _nodes[(idx << 1) | 1], node.v);
  }
  int _offset, _offsetBit;
  vector<Node> _nodes;
};
} // namespace ds
int threshold;
struct LazyCompactSegmentTreeStops : ds::BaseLazyCompactSegmentTree<int, int, int, int> {
  using V = int;
  using InitV = int;
  using Update = int;
  using TraverseArgs = int;
  using Node = typename LazyCompactSegmentTreeStops::Node;
  inline bool _hasUpdate(Node& node) override {
    return false;
  }
  inline void _applyUpdate(const Update& update, Node& node) override {
    node.v = update;
  }
  inline void _clearUpdate(Node& node) override {}
  inline void _initV(InitV initV, Node& node) override {
    node.v = initV;
  }
  inline void _mergeV(const Node& lNode, const Node& rNode, V& res) override {
    res = min(lNode.v, rNode.v);
  }
  inline Traverse _traverse(Node& node, int lower, int upper, TraverseArgs& args) override {
    if (args >= 0 || node.v > threshold) {
      return Traverse::NONE;
    }
    if (node.isLeaf()) {
      args = node.lower + 1;
      return Traverse::NONE;
    }
    int idx = &node - _nodes.data();
    return _nodes[idx << 1].v <= threshold ? Traverse::LEFT : Traverse::RIGHT;
  }
};
const int INF = 1000000000 + 1;
char op[2];
int main() {
  int n, q;
  scanf("%d%d", &n, &q);
  LazyCompactSegmentTreeStops st;
  st.init(vector<int>(n, INF));
  for (int _ = (0); _ < (q); ++_) {
    int cnt, idx;
    scanf("%s%d%d", op, &cnt, &idx);
    --idx;
    if (op[0] == 'M') {
      st.updateRange(idx, idx + 1, cnt);
    } else {
      threshold = cnt;
      int res = -1;
      st.traverseRange(idx, n, res);
      printf("%d\n", res);
    }
  }
  return 0;
}

Compilation message

deda.cpp: In function 'int main()':
deda.cpp:239:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  239 |   scanf("%d%d", &n, &q);
      |   ~~~~~^~~~~~~~~~~~~~~~
deda.cpp:244:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  244 |     scanf("%s%d%d", op, &cnt, &idx);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 0 ms 272 KB Output is correct
2 Correct 1 ms 296 KB Output is correct
3 Correct 2 ms 304 KB Output is correct
4 Correct 146 ms 13040 KB Output is correct
5 Correct 115 ms 8364 KB Output is correct
6 Correct 132 ms 12792 KB Output is correct
7 Correct 143 ms 12876 KB Output is correct