Pagini recente » Cod sursa (job #298877) | Cod sursa (job #800612) | Cod sursa (job #3155373) | Cod sursa (job #3262580) | Cod sursa (job #2658398)
#include <vector>
#include <utility>
#include <cstdlib>
#include <exception>
template<typename T, typename TFunc>
class IntervalTree
{
private:
struct Node
{
size_t a, b;
Node *parent, *left, *right;
T val;
};
public:
IntervalTree(const std::vector<T>* _cont, TFunc _functor) :
functor(std::move(_functor)),
initialCont(_cont),
root(nullptr),
leaves(_cont->size(), nullptr)
{
ConstructTree(0, _cont->size() - 1, &root);
initialCont = nullptr;
}
~IntervalTree()
{
DestructDownwards(&root);
}
void UpdateValue(size_t index, const T& val)
{
leaves[index]->val = val;
UpdateUpwards(leaves[index]);
}
T GetRange(size_t a, size_t b) const
{
return GetRange(leaves[a], a, b);
}
private:
void ConstructTree(const size_t a, const size_t b, Node** node)
{
if (a <= b)
{
(*node) = new Node;
(*node)->parent = (*node)->right = (*node)->left = nullptr;
(*node)->a = a;
(*node)->b = b;
if (a == b)
{
(*node)->val = initialCont->at(a);
leaves[a] = (*node);
}
else
{
const size_t mean = (a + b) / 2;
{
Node* left;
ConstructTree(a, mean, &left);
(*node)->left = left;
(*node)->left->parent = (*node);
}
{
Node* right;
ConstructTree(mean + 1, b, &right);
(*node)->right = right;
(*node)->right->parent = (*node);
}
UpdateNodeValue(*node);
}
}
else
{
(*node) = nullptr;
}
}
void DestructDownwards(Node** node)
{
if ((*node) != nullptr)
{
DestructDownwards(&((*node)->left));
DestructDownwards(&((*node)->right));
delete (*node);
(*node) = nullptr;
}
}
void UpdateNodeValue(Node* node)
{
if (node != nullptr)
{
if ((node->left != nullptr) && (node->right != nullptr))
{
node->val = functor(node->left->val, node->right->val);
}
else
{
if ((node->left != nullptr) && (node->right == nullptr))
{
node->val = node->left->val;
}
else
{
if ((node->left == nullptr) && (node->right != nullptr))
{
node->val = node->right->val;
}
}
}
}
}
void UpdateUpwards(Node* node)
{
if (node != nullptr)
{
UpdateNodeValue(node);
UpdateUpwards(node->parent);
}
}
T GetRange(Node* node, size_t a, size_t b) const
{
if (node->b < b)
{
T* ptrRightVal = nullptr;
if (((node->parent->left == node) && (node->a != a)) || (node->a < a))
{
if (node->right->a >= a)
{
ptrRightVal = &(node->right->val);
}
}
if (ptrRightVal != nullptr)
{
return functor(*ptrRightVal, GetRange(node->parent, a, b));
}
else
{
return GetRange(node->parent, a, b);
}
}
else
{
if (node->b == b)
{
if (node->a >= a)
{
return node->val;
}
else
{
return GetRange(node->right, a, b);
}
}
else
{
if (node->left->b >= b)
{
return GetRange(node->left, a, b);
}
else
{
if (node->left->a >= a)
{
return functor(node->left->val, GetRange(node->right, a, b));
}
else
{
return GetRange(node->right, a, b);
}
}
}
}
}
private:
TFunc functor;
private:
const std::vector<T>* initialCont;
private:
Node* root;
std::vector<Node*> leaves;
};
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int main()
{
size_t n, m;
fin >> n >> m;
vector<int> initialVals(n);
for (size_t i = 0; i < n; ++i)
{
fin >> initialVals[i];
}
IntervalTree<int, int(*)(int, int)> it(&initialVals, [] (int a, int b) { return (a > b) ? a : b; });
for (size_t i = 0; i < m; ++i)
{
int c;
fin >> c;
if (c == 0)
{
size_t a, b;
fin >> a >> b;
fout << it.GetRange(a - 1, b - 1) << '\n';
}
else
{
size_t a;
fin >> a;
int b;
fin >> b;
it.UpdateValue(a - 1, b);
}
}
fin.close();
fout.close();
return 0;
}