Advertisement
Guest User

Untitled

a guest
May 1st, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.27 KB | None | 0 0
  1. template<typename T_Type, typename Function, typename Multiple_Function>
  2. class LazySegmentTree {
  3. struct TreeNode;
  4. typedef std::unique_ptr<TreeNode> uniqueNodePtr_;
  5. typedef TreeNode *nodePtr_;
  6.  
  7. struct TreeNode {
  8. T_Type val_;
  9. bool has_changed_;
  10. uniqueNodePtr_ left_;
  11. uniqueNodePtr_ right_;
  12.  
  13. TreeNode(T_Type val, bool has_changed = true) : val_(val), has_changed_(has_changed), left_(
  14. nullptr), right_(nullptr) {
  15. }
  16. };
  17.  
  18. private:
  19. uniqueNodePtr_ root_;
  20. size_t real_size_;
  21. T_Type default_val_;
  22. Function func_;
  23. Multiple_Function multiple_func_;
  24.  
  25. inline void push(nodePtr_ node) {
  26. if (node->has_changed_) {
  27. if (node->left_ == nullptr) {
  28. node->left_ = uniqueNodePtr_(new TreeNode(node->val_, true));
  29. node->right_ = uniqueNodePtr_(new TreeNode(node->val_, true));
  30. } else {
  31. node->left_->val_ = node->right_->val_ = node->val_;
  32. node->left_->has_changed_ = node->right_->has_changed_ = true;
  33. }
  34. node->has_changed_ = false;
  35. }
  36. }
  37.  
  38. inline T_Type getData(nodePtr_ node, size_t left, size_t right) const {
  39. if (node->has_changed_) {
  40. return multiple_func_(node->val_, right - left);
  41. } else {
  42. return node->val_;
  43. }
  44. }
  45.  
  46. // makes a change from the position "from" to the position "to"
  47. // STL style: [left, right), [from, to)
  48. inline void setRecursive(nodePtr_ node, size_t left, size_t right, size_t from, size_t to,
  49. T_Type val) {
  50. if (from >= right || left >= to) {
  51. return;
  52. }
  53. if (left == from && right == to) {
  54. node->val_ = val;
  55. node->has_changed_ = true;
  56. } else {
  57. push(node);
  58. size_t mid = (left + right) / 2;
  59. setRecursive(node->left_.get(), left, mid, from, std::min(to, mid), val);
  60. setRecursive(node->right_.get(), mid, right, std::max(from, mid), to, val);
  61. node->val_ = func_(getData(node->left_.get(), left, mid),
  62. getData(node->right_.get(), mid, right));
  63. }
  64. }
  65.  
  66. inline const T_Type getRecursive(nodePtr_ node, size_t left, size_t right, size_t from,
  67. size_t to) {
  68. if (from >= right || left >= to) {
  69. return default_val_;
  70. }
  71. if (left == from && right == to) {
  72. return getData(node, left, right);
  73. } else {
  74. push(node);
  75. size_t mid = (left + right) / 2;
  76. T_Type left_ans = getRecursive(node->left_.get(), left, mid, from, std::min(to, mid));
  77. T_Type right_ans = getRecursive(node->right_.get(), mid, right, std::max(from, mid),
  78. to);
  79. node->val_ = func_(getData(node->left_.get(), left, mid),
  80. getData(node->right_.get(), mid, right));
  81. return func_(left_ans, right_ans);
  82. }
  83. }
  84.  
  85. public:
  86. LazySegmentTree(const std::vector<T_Type> &data, T_Type default_val = T_Type(0), Function func = Function(),
  87. Multiple_Function multiple_func = Multiple_Function()) :
  88. root_(uniqueNodePtr_(new TreeNode(default_val))), real_size_(data.size()),
  89. default_val_(default_val), func_(func), multiple_func_(multiple_func) {
  90. for (size_t i = 0; i < real_size_; ++i) {
  91. set(i, data[i]);
  92. }
  93. }
  94.  
  95. inline void set(size_t left, size_t right, T_Type val) {
  96. setRecursive(root_.get(), 0, real_size_, left, right, val);
  97. }
  98.  
  99. inline void set(size_t pos, T_Type val) {
  100. set(pos, pos + 1, val);
  101. }
  102.  
  103. inline const T_Type get(size_t left, size_t right) {
  104. return getRecursive(root_.get(), 0, real_size_, left, right);
  105. }
  106.  
  107. inline const T_Type get(size_t pos) {
  108. return get(pos, pos + 1);
  109. }
  110.  
  111. inline const T_Type get() {
  112. return get(0, real_size_);
  113. }
  114. };
  115.  
  116. template<typename T_Type>
  117. struct TwoVarSum {
  118. inline T_Type operator()(const T_Type &lhs, const T_Type &rhs) const {
  119. return lhs + rhs;
  120. }
  121. };
  122.  
  123. LazySegmentTree<int, TwoVarSum<int>, std::multiplies<int>> tree({5, 7, 3});
  124. std::cout << tree.get(0, 2) << std::endl;
  125. return 0;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement