Skip to content

Instantly share code, notes, and snippets.

@jiunbae
Created September 28, 2015 12:36
Show Gist options
  • Save jiunbae/46be7c756e8ee9a4496e to your computer and use it in GitHub Desktop.
Save jiunbae/46be7c756e8ee9a4496e to your computer and use it in GitHub Desktop.
#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