Created
September 28, 2015 12:36
-
-
Save jiunbae/46be7c756e8ee9a4496e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include <algorithm> | |
#include <functional> | |
using namespace std; | |
template<typename type> | |
class IndexTree { | |
private: | |
std::vector<type> elements; | |
size_t e_size, t_size; | |
std::function<type(type, type)> Comp = [](type first, type second)->type {return first + second;}; | |
type qquery(size_t node, size_t begin, size_t end, size_t left, size_t right) | |
{ | |
left = this->max(left, begin); | |
right = this->min(right, end); | |
if (left > right) | |
return SIZE_MAX; | |
else if (left == begin && right == end) | |
return this->elements.at(node); | |
size_t mid = (begin + end) / 2; | |
type query_left = qquery(node * 2, begin, mid, left, right), | |
query_right = qquery(node * 2 + 1, mid + 1, end, left, right), | |
result = 0; | |
if (query_left != SIZE_MAX) | |
result += query_left; | |
if (query_right != SIZE_MAX) | |
result += query_right; | |
return result; | |
} | |
void uupdate(size_t index) | |
{ | |
if (index) | |
{ | |
int t = Comp(1, 2); | |
this->elements.at(index) = Comp(this->elements.at(index * 2), this->elements.at(index * 2 + 1)); | |
uupdate(index / 2); | |
} | |
return; | |
} | |
type operator[](const size_t index) const { | |
return this->elements.at(index + this->t_size); | |
} | |
public: | |
IndexTree() {} | |
IndexTree(std::vector<type> vector) | |
{ | |
this->Initilize(vector); | |
} | |
void Initilize(std::vector<type> vector) | |
{ | |
this->e_size = vector.size(); | |
this->t_size = pow(2., (int)log2(this->e_size) + 1); | |
this->elements.assign(this->t_size * 2, 0); | |
for (size_t index = 0; index < e_size; index++) | |
this->elements.at(t_size + index) = vector.at(index); | |
} | |
void re_order() | |
{ | |
for (size_t index = 0; index < this->e_size; index++) | |
this->update(index, this->elements.at(index + this->t_size)); | |
return; | |
} | |
void setComp(function<type(type, type)> func) | |
{ | |
this->Comp = func; | |
return this->re_order(); | |
} | |
void update(size_t index, type value) | |
{ | |
this->elements.at(index + this->t_size) = value; | |
return this->uupdate((index + this->t_size) / 2); | |
} | |
std::vector<type> vector() | |
{ | |
std::vector<type> result(this->elements.begin() + this->t_size, this->elements.end()); | |
return result; | |
} | |
type query(size_t left, size_t right) | |
{ | |
return this->qquery(1, 0, this->t_size - 1, left, right); | |
} | |
type at(size_t index) | |
{ | |
return this->elements.at(this->t_size + index); | |
} | |
type max(type first, type second) { return first > second ? first : second; } | |
type min(type first, type second) { return first > second ? second : first; } | |
type sum(type first, type second) { return first + second; } | |
~IndexTree() | |
{ } | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment