Cod sursa(job #3201625)

Utilizator MagicantPlusIuoras Andrei MagicantPlus Data 9 februarie 2024 11:30:42
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.71 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>

using namespace std;

ifstream fin("arbint.in");
ofstream fout("arbint.out");

#define cin fin
#define cout fout

struct node_
{
    int left, right, val;
    node_ *leftChild, *rightChild;

    node_()
    {
        this->leftChild = NULL;
        this->rightChild = NULL;
        this->val = 0;
    }

    void operator=(node_ x)
    {
        this->left = x.left;
        this->right = x.right;
        this->val = x.val;
        this->leftChild = x.leftChild;
        this->rightChild = x.rightChild;
    }
};

struct segmentTree_
{
    node_ *root_;

    segmentTree_();
    segmentTree_(vector<int>& elements);
    node_* insertNode(node_ *location, bool leftRight, node_ val);
    void build(vector<int>& elements);
    void build_(node_* node, vector<int>& elements);
    void clear();
    void update(int index, int val);
    void update_(node_* node, int index, int val);
    int query(int left, int right);
    int query_(node_* node, int left, int right);
};

node_ makeNode(int left, int right, int val = 0, node_ *leftChild = NULL, node_ *rightChild = NULL);

int main()
{
    int n, q;
    vector<int> elements;
    segmentTree_ segmentTree;

    cin >> n >> q;
    elements.resize(n);

    for(int i = 0; i < n; i++)
    {
        cin >> elements[i];
    }

    segmentTree.build(elements);

    for(int i = 0, queryType, a, b; i < q; i++)
    {
        cin >> queryType >> a >> b;

        if(queryType == 0)
        {   
            a--;
            b--;

            cout << segmentTree.query(a, b) << '\n';
        }
        else
        {   
            a--;
            segmentTree.update(a, b);
        }
    }

    return 0;
}

node_ makeNode(int left, int right, int val, node_ *leftChild, node_ *rightChild)
{
    node_ temp;

    temp.left = left;
    temp.right = right;
    temp.val = val;
    temp.leftChild = leftChild;
    temp.rightChild = rightChild;

    return temp;
}
segmentTree_::segmentTree_()
{
    this->root_ = NULL;
}
segmentTree_::segmentTree_(vector<int>& elements)
{
    this->root_ = NULL;
    this->build(elements);
}
node_* segmentTree_::insertNode(node_ *location, bool leftRight, node_ val)
{
    node_* newNode = new node_;

    *newNode = val;

    if(leftRight == 0)
    {
        location->leftChild = newNode;
    }
    else
    {
        location->rightChild = newNode;
    }

    return newNode;
}
void segmentTree_::build(vector<int>& elements)
{
    if(elements.size() == 0)
        return;

    this->clear();

    this->root_ = new node_;
    this->root_->left = 0;
    this->root_->right = elements.size() - 1;

    this->build_(this->root_, elements);
}
void segmentTree_::build_(node_* node, vector<int>& elements)
{
    if(node->left == node->right)
    {
        node->val = elements[node->left];
    }
    else
    {
        int middle = (node->left + node->right) / 2;

        insertNode(node, 0, makeNode(node->left, middle));
        insertNode(node, 1, makeNode(middle + 1, node->right));

        build_(node->leftChild, elements);
        build_(node->rightChild, elements);

        node->val = max(node->leftChild->val, node->rightChild->val);
    }
}
void segmentTree_::clear()
{   
    if(this->root_ == NULL)
    {
        return;
    }

    queue<node_*> bfs;
    node_* node;

    bfs.push(this->root_);

    while(!bfs.empty())
    {
        node = bfs.front();
        bfs.pop();

        if(node->leftChild != NULL)
        {
            bfs.push(node->leftChild);
        }
        
        if(node->rightChild != NULL)
        {
            bfs.push(node->rightChild);
        }

        delete node;
    }

    this->root_ = NULL;
}
void segmentTree_::update(int index, int val)
{
    if(this->root_ != NULL)
    {
        this->update_(this->root_, index, val);
    }
}
void segmentTree_::update_(node_* node, int index, int val)
{
    if(node->left == node->right)
    {
        node->val = val;
    }
    else
    {
        int middle = (node->left + node->right) / 2;

        if(index <= middle)
        {
            update_(node->leftChild, index, val);
        }
        else
        {
            update_(node->rightChild, index, val);
        }

        node->val = max(node->leftChild->val, node->rightChild->val);
    }
}
int segmentTree_::query(int left, int right)
{
    if(this->root_ == NULL)
    {
        return -2;
    }

    return query_(this->root_, left, right);
}
int segmentTree_::query_(node_* node, int left, int right)
{
    if(left <= node->left && node->right <= right)
    {
        return node->val;
    }
    else if(node->right >= left && node->left <= right)    
    {
        return max(query_(node->leftChild, left, right), query_(node->rightChild, left, right));
    }

    return -1;
}