kyopro-lib

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:warning: Segment tree (Add $ai + b$, Range sum)
(Mylib/DataStructure/SegmentTree/segment_tree_linear_add_range_sum.cpp)

Operations

Requirements

Notes

Problems

References

Code

#pragma once
#include <utility>
#include <vector>

namespace haar_lib {
  template <typename T>
  class segment_tree_linear_add_range_sum {
  public:
    using value_type = T;

  private:
    using P = std::pair<T, T>;

    int depth_, size_, hsize_;
    std::vector<T> data_;
    std::vector<P> lazy_;

  public:
    segment_tree_linear_add_range_sum() {}
    segment_tree_linear_add_range_sum(int n) : depth_(n > 1 ? 32 - __builtin_clz(n - 1) + 1 : 1),
                                               size_(1 << depth_),
                                               hsize_(size_ / 2),
                                               data_(size_, T()),
                                               lazy_(size_, P()) {}

  private:
    P add(P a, P b) {
      return {a.first + b.first, a.second + b.second};
    }

    void propagate(int i, int l, int r) {
      if (lazy_[i] == P()) return;
      if (i < hsize_) {
        auto t            = lazy_[i];
        lazy_[i << 1 | 0] = add(t, lazy_[i << 1 | 0]);
        t.first += t.second * ((r - l) / 2);
        lazy_[i << 1 | 1] = add(t, lazy_[i << 1 | 1]);
      }
      const int len     = r - l;
      const auto [s, d] = lazy_[i];
      data_[i] += len * (s * 2 + d * (len - 1)) / 2;
      lazy_[i] = P();
    }

    T update(int i, int l, int r, int s, int t, T a, T b) {
      propagate(i, l, r);
      if (r <= s or t <= l) return data_[i];
      if (s <= l and r <= t) {
        lazy_[i] = add(lazy_[i], std::make_pair(b + (l - s) * a, a));
        propagate(i, l, r);
        return data_[i];
      }
      return data_[i] =
                 update(i << 1 | 0, l, (l + r) / 2, s, t, a, b) +
                 update(i << 1 | 1, (l + r) / 2, r, s, t, a, b);
    }

    T get(int i, int l, int r, int x, int y) {
      propagate(i, l, r);
      if (r <= x or y <= l) return 0;
      if (x <= l and r <= y) return data_[i];
      return get(i << 1 | 0, l, (l + r) / 2, x, y) +
             get(i << 1 | 1, (l + r) / 2, r, x, y);
    }

  public:
    void update(int l, int r, T a, T b) {
      update(1, 0, hsize_, l, r, a, b);
    }

    T fold(int l, int r) {
      return get(1, 0, hsize_, l, r);
    }

    T operator[](int i) {
      return fold(i, i + 1);
    }
  };
}  // namespace haar_lib
#line 2 "Mylib/DataStructure/SegmentTree/segment_tree_linear_add_range_sum.cpp"
#include <utility>
#include <vector>

namespace haar_lib {
  template <typename T>
  class segment_tree_linear_add_range_sum {
  public:
    using value_type = T;

  private:
    using P = std::pair<T, T>;

    int depth_, size_, hsize_;
    std::vector<T> data_;
    std::vector<P> lazy_;

  public:
    segment_tree_linear_add_range_sum() {}
    segment_tree_linear_add_range_sum(int n) : depth_(n > 1 ? 32 - __builtin_clz(n - 1) + 1 : 1),
                                               size_(1 << depth_),
                                               hsize_(size_ / 2),
                                               data_(size_, T()),
                                               lazy_(size_, P()) {}

  private:
    P add(P a, P b) {
      return {a.first + b.first, a.second + b.second};
    }

    void propagate(int i, int l, int r) {
      if (lazy_[i] == P()) return;
      if (i < hsize_) {
        auto t            = lazy_[i];
        lazy_[i << 1 | 0] = add(t, lazy_[i << 1 | 0]);
        t.first += t.second * ((r - l) / 2);
        lazy_[i << 1 | 1] = add(t, lazy_[i << 1 | 1]);
      }
      const int len     = r - l;
      const auto [s, d] = lazy_[i];
      data_[i] += len * (s * 2 + d * (len - 1)) / 2;
      lazy_[i] = P();
    }

    T update(int i, int l, int r, int s, int t, T a, T b) {
      propagate(i, l, r);
      if (r <= s or t <= l) return data_[i];
      if (s <= l and r <= t) {
        lazy_[i] = add(lazy_[i], std::make_pair(b + (l - s) * a, a));
        propagate(i, l, r);
        return data_[i];
      }
      return data_[i] =
                 update(i << 1 | 0, l, (l + r) / 2, s, t, a, b) +
                 update(i << 1 | 1, (l + r) / 2, r, s, t, a, b);
    }

    T get(int i, int l, int r, int x, int y) {
      propagate(i, l, r);
      if (r <= x or y <= l) return 0;
      if (x <= l and r <= y) return data_[i];
      return get(i << 1 | 0, l, (l + r) / 2, x, y) +
             get(i << 1 | 1, (l + r) / 2, r, x, y);
    }

  public:
    void update(int l, int r, T a, T b) {
      update(1, 0, hsize_, l, r, a, b);
    }

    T fold(int l, int r) {
      return get(1, 0, hsize_, l, r);
    }

    T operator[](int i) {
      return fold(i, i + 1);
    }
  };
}  // namespace haar_lib
Back to top page