ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

线段树 C++实现 树形式

2022-08-28 15:31:42  阅读:169  来源: 互联网

标签:rt Node lazy int 线段 形式 C++ rchild lchild


网上看了一圈,看到几个都是用数组实现的
我用树结构重写了一遍

#ifndef SEGMENTTREE_H
#define SEGMENTTREE_H
#include <vector>

template<typename T>
class SegmentTree {
   public:
      SegmentTree(std::vector<T> &a) {
            int N = a.size();
            this->a = a;
            this->root = new _Node();
            this->_build(0, N-1, this->root);
      };

      virtual ~SegmentTree() {
            delete this->root;
      };

      void updateElement(T value, int index) {
            this->_updateSegment(value, index, index, this->root);
      }

      void updateSegment(T c, int l, int r) {
            this->_updateSegment(c, l, r, this->root);
      };

      T querySegment(int l, int r) {
            return this->_querySegment(l,r, this->root);
      };
   private:
      struct _Node {
            _Node* rchild;
            _Node* lchild;
            int l, r, lazy;
            T sum;

            _Node() {
                  this->rchild = nullptr;
                  this->lchild = nullptr;
                  this->l = -1;
                  this->r = -1;
                  this->lazy = -1;
                  this->sum = 0;
            }

            ~_Node() {
                  delete this->rchild;
                  delete this->lchild;
            }

            int mid() {
                  return (l+r) >> 1;
            };

            void _pushUp() {
                  this->sum = this->rchild->sum + this->lchild->sum;
            };

            void _pushDown(int length) {
                  // lazy load
                  if(this->lazy) {
                        // push down the lazy value into children
                        this->lchild->lazy += this->lazy;
                        this->rchild->lazy += this->lazy;
                        this->lchild->sum += this->lazy * (length-(length>>1));
                        this->rchild->sum += this->lazy * (length>>1);
                        this->lazy = 0;
                  }
            };
      };
      _Node *root;

      std::vector<T> a;

      void _build(int l, int r, _Node *rt) {
            rt->l = l;
            rt->r = r;
            rt->lazy = 0;
            rt->rchild = new _Node();
            rt->lchild = new _Node();

            if(l == r) {
                  rt->sum = this->a[l];
                  return ;
            }

            int m = rt->mid();
            this->_build(l, m, rt->lchild);
            this->_build(m+1, r, rt->rchild);
            rt->_pushUp();
      };

      void _updateSegment(T value, int l, int r, _Node *rt) {
            if(rt->l == l && rt->r == r) {
                  rt->lazy += value;
                  rt->sum += value * (r-l+1);
                  return;
            }

            if(rt->l == rt->r) return ;

            rt->_pushDown(rt->r - rt->l + 1);

            int m = rt->mid();
            if(r <= m) this->_updateSegment(value, l, r, rt->lchild);
            else if(l > m) this->_updateSegment(value, l, r, rt->rchild);
            else {
                  this->_updateSegment(value, l, m, rt->lchild);
                  this->_updateSegment(value, m+1, r, rt->rchild);
            }

            rt->_pushUp();
      };

      T _querySegment(int l, int r, _Node *rt) {
            if(l == rt->l && r == rt->r) {
                  return rt->sum;
            }

            rt->_pushDown(rt->r - rt->l + 1);

            T ans = 0;
            int m = rt->mid();
            if(r <= m) ans += this->_querySegment(l, r, rt->lchild);
            else if(l > m) ans += this->_querySegment(l, r, rt->rchild);
            else {
                  ans += this->_querySegment(l, m, rt->lchild);
                  ans += this->_querySegment(m+1, r, rt->rchild);
            }
            return ans;
      }
};
#endif // SEGMENTTREE_H

标签:rt,Node,lazy,int,线段,形式,C++,rchild,lchild
来源: https://www.cnblogs.com/neumy/p/16632830.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有