ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SegmentTree
    232's competitive-programming templates. 2024. 8. 25. 11:21
    template <typename Segment>
    struct SegmentTree {
      int n;
      mutable std::vector<Segment> a;
    
      void pull(int x, int l, int r) {
        int m = l + (r - l) / 2;
        a[x] = a[x + 1] + a[x + 2 * (m - l)];
      }
    
      explicit SegmentTree(int arg_n) : n(arg_n) {
        assert(n > 0);
        a.resize(2 * n - 1);
        auto build = [&](auto&& self, int x, int l, int r) -> void {
          if (r - l == 1) {
            return;
          }
          int m = l + (r - l) / 2;
          self(self, x + 1, l, m);
          self(self, x + 2 * (m - l), m, r);
          pull(x, l, r);
        };
        build(build, 0, 0, n);
      }
    
      template <typename M>
      explicit SegmentTree(const std::vector<M>& v) {
        assert(!v.empty());
        n = int(v.size());
        a.resize(2 * n - 1);
        auto build = [&](auto&& self, int x, int l, int r) -> void {
          if (r - l == 1) {
            a[x] = Segment(v[l]);
            return;
          }
          int m = l + (r - l) / 2;
          self(self, x + 1, l, m);
          self(self, x + 2 * (m - l), m, r);
          pull(x, l, r);
        };
        build(build, 0, 0, n);
      }
    
      template <typename... Types>
      void modifyImpl(int x, int l, int r, int p, Types&&... args) {
        if (r - l == 1) {
          a[x].apply(args...);
          return;
        }
        int m = l + (r - l) / 2;
        if (p < m) {
          modifyImpl(x + 1, l, m, p, args...);
        } else {
          modifyImpl(x + 2 * (m - l), m, r, p, args...);
        }
        pull(x, l, r);
      }
    
      template <typename... Types>
      void modify(int p, Types&&... args) {
        assert(0 <= p && p < n);
        modifyImpl(0, 0, n, p, args...);
      }
    
      Segment getImpl(int x, int l, int r, int ll, int rr) const {
        if (ll <= l && r <= rr) {
          return a[x];
        }
        int m = l + (r - l) / 2;
        if (rr <= m) {
          return getImpl(x + 1, l, m, ll, rr);
        } else if (m <= ll) {
          return getImpl(x + 2 * (m - l), m, r, ll, rr);
        } else {
          return getImpl(x + 1, l, m, ll, rr) + getImpl(x + 2 * (m - l), m, r, ll, rr);
        }
      }
    
      Segment get(int ll, int rr) const {
        assert(0 <= ll && ll < rr && rr <= n);
        return getImpl(0, 0, n, ll, rr);
      }
    
      template <typename F>
      int findFirstImpl(int x, int l, int r, int ll, int rr, F&& func) const {
        if (rr <= l || r <= ll) {
          return -1;
        }
        if (ll <= l && r <= rr && !func(a[x])) {
          return -1;
        }
        if (r - l == 1) {
          return l;
        }
        int m = l + (r - l) / 2;
        int res = findFirstImpl(x + 1, l, m, ll, rr, func);
        if (res == -1) {
          res = findFirstImpl(x + 2 * (m - l), m, r, ll, rr, func);
        }
        return res;
      }
    
      template <typename F>
      int findFirst(int ll, int rr, F&& func) const {
        return findFirstImpl(0, 0, n, ll, rr, func);
      }
    
      template <typename F>
      int findLastImpl(int x, int l, int r, int ll, int rr, F&& func) const {
        if (rr <= l || r <= ll) {
          return -1;
        }
        if (ll <= l && r <= rr && !func(a[x])) {
          return -1;
        }
        if (r - l == 1) {
          return l;
        }
        int m = l + (r - l) / 2;
        int res = findLastImpl(x + 2 * (m - l), m, r, ll, rr, func);
        if (res == -1) {
          res = findLastImpl(x + 1, l, m, ll, rr, func);
        }
        return res;
      }
    
      template <typename F>
      int findLast(int ll, int rr, F&& func) const {
        return findLastImpl(0, 0, n, ll, rr, func);
      }
    };

    '232's competitive-programming templates.' 카테고리의 다른 글

    Rmq  (0) 2024.08.26
    radix  (0) 2024.08.26
    Queue  (0) 2024.08.23
    Deque  (0) 2024.08.23
    SlidingDeque  (0) 2024.08.23
Designed by Tistory.