Cod sursa(job #2241846)

Utilizator FlaviusFeteanFetean Flavius FlaviusFetean Data 17 septembrie 2018 10:18:13
Problema Arbori de intervale Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.12 kb
#include <iostream>
#include <fstream>
#include <queue>

using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");

queue<int> v;

struct node{
    int info_maxVal;
    int lower_bound, upper_bound;
    node *left_SubTree = NULL, *right_SubTree = NULL;
} *root;

node* create_intervalTree(int a, int b)
{
    node *new_node = new node;
    if(a == b){
        new_node->lower_bound = new_node->upper_bound = a;
        new_node->info_maxVal = v.front(), v.pop();
        return new_node;
    }
    new_node->lower_bound = a, new_node->upper_bound = b;

    new_node->left_SubTree = create_intervalTree(a, (a + b) / 2);
    new_node->right_SubTree = create_intervalTree((a + b) / 2 + 1, b);

    new_node->info_maxVal = max(new_node->left_SubTree->info_maxVal, new_node->right_SubTree->info_maxVal);
    return new_node;
}

bool isNot_leaf(node* x){ return (x->lower_bound != x->upper_bound); }

int maxIn_interval(int a, int b)
{
    node *left_bound, *right_bound, *luke_nodeWalker;
    luke_nodeWalker = root; int l, r;

    while(1){
        l = luke_nodeWalker->lower_bound, r = luke_nodeWalker->upper_bound;
        if(a > (l + r) / 2) luke_nodeWalker = luke_nodeWalker->right_SubTree;
        else if(b <= (l + r) / 2) luke_nodeWalker = luke_nodeWalker->left_SubTree;
        else break;
    }

    right_bound = luke_nodeWalker->right_SubTree; left_bound = luke_nodeWalker->left_SubTree;
    l = left_bound->info_maxVal; r = right_bound->info_maxVal;
    while(isNot_leaf(left_bound) || isNot_leaf(right_bound)){
        if(isNot_leaf(left_bound))
            if(a > (left_bound->lower_bound + left_bound->upper_bound) / 2)
                l = left_bound->right_SubTree->info_maxVal,
                left_bound = left_bound->right_SubTree;
            else left_bound = left_bound->left_SubTree;

        if(isNot_leaf(right_bound))
            if(b <= (right_bound->lower_bound + right_bound->upper_bound) / 2)
                r = right_bound->left_SubTree->info_maxVal,
                right_bound = right_bound->left_SubTree;
            else right_bound = right_bound->right_SubTree;
    }

    return max(l,r);
}

int updateTree(int a, int b, node* modified_node)
{
    if(modified_node->lower_bound == a && modified_node->upper_bound == a){
        modified_node->info_maxVal = b; return modified_node->info_maxVal;
    }
    if(a > (modified_node->lower_bound + modified_node->upper_bound) / 2)
        modified_node->info_maxVal =
        max(updateTree(a, b, modified_node->right_SubTree), modified_node->left_SubTree->info_maxVal);
    else modified_node->info_maxVal =
        max(updateTree(a, b, modified_node->left_SubTree), modified_node->right_SubTree->info_maxVal);
    return modified_node->info_maxVal;
}

int main()
{
    int n, x, i, a, b, m; bool t;
    fin >> n >> m;

    for(i = 1; i <= n; i++){
        fin >> x; v.push(x);
    }

    root = create_intervalTree(1, n);

    for(i = 1; i <= m; i++)
    {
        fin >> t >> a >> b;
        if(t) updateTree(a, b, root);
        else fout << maxIn_interval(a, b) << "\n";
    }

    return 0;
}