アットウィキロゴ

segment木

点更新と区間[a,b)に対するクエリがO(logN)でできる
http://tubo28.me/algorithm/segtree_monoids/
http://beet-aizu.hatenablog.com/entry/2017/09/10/132258

+ ソースコード
  1. template <typename monoid>
  2. class segmentTree {
  3. public:
  4. using M = monoid;
  5. using T = typename M::value_type;
  6.  
  7. int sz;
  8. vector<T> x;
  9.  
  10. segmentTree(int n = 1e5) {
  11. sz = 1; while(sz < n) sz *= 2;
  12. init();
  13. }
  14. void init() { x.assign(sz*2, M::id()); }
  15.  
  16. // [a, b)
  17. T query(int a, int b, int k, int l, int r) {
  18. if(r <= a || b <= l) return M::id();
  19. if(a <= l && r <= b) return x[k];
  20. return M::f(query(a, b, 2*k+1, l, (l+r)/2),
  21. query(a, b, 2*k+2, (l+r)/2, r));
  22. }
  23. T query(int a, int b) {return query(a, b, 0, 0, sz);}
  24. // 点更新
  25. void update(int i, const T &val) {
  26. i += sz-1;
  27. x[i] = M::g(x[i], val);
  28. while(i > 0) {
  29. i = (i-1) / 2;
  30. x[i] = M::f(x[i*2+1], x[i*2+2]);
  31. }
  32. }
  33. };
  34.  
  35. template <typename T>
  36. struct min_monoid {
  37. using value_type = T;
  38. static constexpr T id() { return std::numeric_limits<T>::max(); }
  39. static T f(const T &a, const T &b) { return min(a, b); }
  40. static T g(const T &a, const T &b) { return b; }
  41. };
  42. template <typename T>
  43. struct max_monoid {
  44. using value_type = T;
  45. static constexpr T id() { return std::numeric_limits<T>::min; }
  46. static T f(const T &a, const T &b) { return max(a, b); }
  47. static T g(const T &a, const T &b) { return b; }
  48. };
  49. template <typename T>
  50. struct sum_monoid {
  51. using value_type = T;
  52. static constexpr T id() {return 0;}
  53. static T f(const T &a, const T &b) { return a+b; }
  54. static T g(const T &a, const T &b) { return a+b; }
  55. };
  56.  
  57. template <typename T>
  58. using rmq = segmentTree<min_monoid<T>>;
  59. template <typename T>
  60. using rsq = segmentTree<sum_monoid<T>>;
  61.  
最終更新:2018年02月13日 20:12