Cod sursa(job #2456288)

Utilizator HerddexJinga Tudor Herddex Data 14 septembrie 2019 09:38:49
Problema Datorii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.73 kb
#include <fstream>

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

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

class IntervalTree {
private:
    struct IntervalTreeNode {
        int lowerBound;
        int upperBound;
        int sumOverInterval;
        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->sumOverInterval = 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->sumOverInterval = node->leftSon->sumOverInterval + node->rightSon->sumOverInterval;
        }
    }

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

    void recusivelyUpdateTree(IntervalTreeNode *node, int &position, int &value) {
        node -> sumOverInterval -= 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);
        }
    }

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

        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 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 findSumOverInterval(int a, int b) {
        return recursivelyInterrogateTree(treeHead, a, b);
    }
};

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

    //tree.printTree();

	for(int op; M; M--) {
        fin >> op;
        if(op == 0) {
            int pos, value;
            fin >> pos >> value;
            tree.updateArrayElement(pos, value);
            //tree.printTree();
        }
        else if(op == 1) {
            int a, b;
            fin >> a >> b;
            fout << tree.findSumOverInterval(a, b) << '\n';
        }
	}

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