aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/dsa/BinaryIndexTree.h
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/dsa/BinaryIndexTree.h')
-rw-r--r--meowpp/dsa/BinaryIndexTree.h155
1 files changed, 92 insertions, 63 deletions
diff --git a/meowpp/dsa/BinaryIndexTree.h b/meowpp/dsa/BinaryIndexTree.h
index 36f24d7..5525c62 100644
--- a/meowpp/dsa/BinaryIndexTree.h
+++ b/meowpp/dsa/BinaryIndexTree.h
@@ -4,70 +4,99 @@
#include <cstdlib>
#include <vector>
+#include <algorithm>
-namespace meow{
- //#
- //#=== meow:: *BinaryIndexTree<Value>* (C++ class)
- //#==== Description
- //# 極度簡化版的 `SegmentTree` 已無法區間操作, 區間詢問的區間開頭也一定要
- //# 在 `index=0` 的地方
- //#
- //#==== Template Class Operators Request
- //#[options="header",width="70%",cols="1>m,1<,3<s,5<,3<,15<",grid="rows"]
- //#|=====================================================================
- //#|Const?|Typename| Operator | Parameters | Return_Type| Description
- //#|const | Value | operator+ |(Value `n`) | Value | 合併用(類似
- //# `SegmentTree` 的
- //# operator{b} )
- //#|=====================================================================
- //#
- template<class Value>
- class BinaryIndexTree{
- private:
- std::vector<Value> _array;
- public:
- BinaryIndexTree();
- BinaryIndexTree(size_t __size, Value const& __value);
- BinaryIndexTree(BinaryIndexTree const& __tree2);
-
- //#==== Support Methods
- //#
- //# * N <- `this` 中擁有的資料數
- //#
- //#[options="header",width="100%",cols="1>m,3>s,7<,3<,3^,20<",grid="rows"]
- //#|=====================================================================
- //#|Const?|Name | Parameters | Return_Type| Time_Complexity| Description
-
-
- //#||reset|(size_t `size`, Value const& `value`)|void|O(`size`)
- //#|將資料長度刷成 `N = size` 且每一個元素都是 `value`
- void reset(size_t __size, Value const& __value);
-
-
- //#||update|(size_t `index`, Value const& `value`)|void|O(logN)
- //#|將第 `index` (從零開始算) 多加上 `value`
- void update( size_t __index, Value const& __value);
-
-
- //#|const|query|(size_t `index`)|void|O(logN)
- //#|詢問 `0~index` 的區間值
- Value query (ssize_t __index) const;
-
-
- //#|=====================================================================
- };
- //#
- //#[NOTE]
- //#========================================
- //# * 一般來說只能用在維護區間總和, 維護區間最大值只有在特殊情況才可以, 即
- //# '針對每個元素, 每次 update() 的值一定會大於等於原本的值'
- //# * 若要用區間最大值 , 則 `Value` 的 `operator+` 要寫成 `std::max(...)`
- //#========================================
- //#
- //# '''
-}
+namespace meow {
-#include "BinaryIndexTree.hpp"
+template<class Value>
+/*!
+ * @brief 極度簡化的 \c SegmentTree 已無區間更新的操作
+ *
+ * 一般來說只能用在維護區間總和, 維護區間最大值只有在特殊情況才可以, 即
+ * \b 針對每個元素, \b 每次update() \b 的值一定會大於等於原本的值 .
+ * 若要用區間最大值 , 則 \a Value 的 \c operator+ 要寫成 \c std::max(...)
+ *
+ * @author cat_leopard
+ */
+class BinaryIndexTree {
+private:
+ std::vector<Value> array_;
+public:
+ /*!
+ * @brief constructor
+ */
+ BinaryIndexTree() {
+ }
-#endif // dsa_BinaryIndexTree_H__
+ /*!
+ * @brief constructor
+ *
+ * @param [in] size 要維護的區間大小 \b [0,size)
+ * @param [in] value 預設值
+ */
+ BinaryIndexTree(size_t size, Value const& value):
+ array_(size, value) {
+ }
+
+ /*!
+ * @brief constructor
+ *
+ * 將另一個 \c BinaryIndexTree 原封不動的複製過來
+ * @param [in] tree2 另外一個 \c BinaryIndexTree
+ */
+ BinaryIndexTree(BinaryIndexTree const& tree2):
+ array_(tree2.array_) {
+ }
+
+ /*!
+ * @brief 將資料洗掉, 重設
+ *
+ * 時間複雜度\b O(N)
+ *
+ * @param [in] size 要維護的區間大小 \b [0,size)
+ * @param [in] init 預設值
+ * @return 無
+ */
+ void reset(size_t size, Value const& init) {
+ array_.clear();
+ array_.resize(size, init);
+ }
+
+ /*!
+ * @brief 將array中第 \a index (從零算起)個element多加上指定的值
+ *
+ * 時間複雜度\b O(logN)
+ *
+ * @param [in] index 指定的index
+ * @param [in] value 指定的值
+ * @return 無
+ */
+ void update(size_t index, Value const& value) {
+ index++;
+ for ( ; index <= array_.size(); index += (index & -index)) {
+ array_[index - 1] = array_[index - 1] + value;
+ }
+ }
+
+ /*!
+ * @brief 詢問 \a 0~index 的區間值
+ *
+ * 時間複雜度\b O(logN)
+ *
+ * @param [in] index 指定的index
+ * @return 區間值
+ */
+ Value query(ssize_t index) const {
+ index = std::min(index + 1, (ssize_t)array_.size());
+ Value ret(0);
+ for ( ; 0 < index; index -= (index & -index)) {
+ ret = ret + array_[index - 1];
+ }
+ return ret;
+ }
+};
+
+}
+
+#endif // dsa_BinaryIndexTree_H__