Cod sursa(job #2455786)

Utilizator HerddexJinga Tudor Herddex Data 12 septembrie 2019 18:46:29
Problema Arbori de intervale Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.76 kb
#include <fstream>

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

int average(int a, int b) {
    return (a + b) / 2;
}

int max(int a, int b) {
    return a > b ? a : b;
}

class IntervalTree {
private:
    struct IntervalTreeNode {
        int lowerBound;
        int upperBound;
        int maxOverInterval;
        IntervalTreeNode *leftSon;
        IntervalTreeNode *rightSon;
    } *treeHead;
    int *elementArray;

    void recursivelyGenerateNode(IntervalTreeNode *node, int lowerBound, int upperBound) {

        node->lowerBound = lowerBound;
        node->upperBound = upperBound;

        if(lowerBound == upperBound) {
            node->maxOverInterval = elementArray[lowerBound];
            node->leftSon = 0;
            node->rightSon = 0;
        }
        else {
            node->leftSon = new IntervalTreeNode;
            recursivelyGenerateNode(node->leftSon, lowerBound, average(lowerBound, upperBound));
            node->rightSon = new IntervalTreeNode;
            recursivelyGenerateNode(node->rightSon, average(lowerBound, upperBound) + 1, upperBound);
            node->maxOverInterval = max(node->leftSon->maxOverInterval, node->rightSon->maxOverInterval);
        }
    }

    void recursivelyPrintTree(IntervalTreeNode *head) {
        fout << '[' << head->lowerBound << ',' << head->upperBound << "]: " << head->maxOverInterval << '\n';
        if(head->lowerBound < head->upperBound) {
            recursivelyPrintTree(head->leftSon);
            recursivelyPrintTree(head->rightSon);
        }
    }

    void recusivelyUpdateTree(IntervalTreeNode *node, int &position, int &value) {
        if(node->lowerBound < node->upperBound) {
            int middle = average(node -> lowerBound, node -> upperBound);
            if(position <= middle)
                recusivelyUpdateTree(node->leftSon, position, value);
            else
                recusivelyUpdateTree(node->rightSon, position, value);
            node->maxOverInterval = max(node->leftSon->maxOverInterval, node->rightSon->maxOverInterval);
        }
        else
            node->maxOverInterval = value;
    }

    int recursivelyInterrogateTree(IntervalTreeNode *node, int a, int b) {
        if(a == node->lowerBound && b == node->upperBound)
            return node->maxOverInterval;

        int middle = average(node->lowerBound, node->upperBound);
        if (a > middle)
            return recursivelyInterrogateTree(node->rightSon, a, b);
        else if (b <= middle)
            return recursivelyInterrogateTree(node->leftSon, a, b);
        else
            return max(recursivelyInterrogateTree(node->leftSon, a, middle), recursivelyInterrogateTree(node->rightSon, middle + 1, b));
    }

public:
    IntervalTree (int arraySize) {
        elementArray = new int[arraySize + 1];
        for(int i = 1; i <= arraySize; i++)
            fin >> elementArray[i];
        treeHead = new IntervalTreeNode;
        recursivelyGenerateNode(treeHead, 1, arraySize);
    }

    void printTree() {
        recursivelyPrintTree(treeHead);
        fout << '\n';
    }

    void updateArrayElement(int position, int value) {
        recusivelyUpdateTree(treeHead, position, value);
        elementArray[position] = value;
    }

    int findMaxOverInterval(int a, int b) {
        return recursivelyInterrogateTree(treeHead, a, b);
    }
};

int main() {
    int N, M;
    fin >> N >> M;

    IntervalTree tree(N);
    for(; M; M--) {
        int operation, a, b;
        fin >> operation >> a >> b;

        if(operation == 0)
            fout << tree.findMaxOverInterval(a, b) << '\n';
        else
            tree.updateArrayElement(a, b);
    }

	fin.close();
	fout.close();
	return 0;
}