Cod sursa(job #2099181)

Utilizator Andreiii500Andrei Puiu Andreiii500 Data 4 ianuarie 2018 02:56:16
Problema Datorii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.28 kb
#include<algorithm>
#include<iostream>
#include<fstream>
using namespace std;

ifstream in("datorii.in");
ofstream out("datorii.out");

struct interval
{
    int leftBoundary, rightBoundary;
    int value; /// The values of its son and itself :)
    interval *leftSon, *rightSon;
};

const int N = 15001;

void createSons(interval *x)
{
    x->value = 0;

    ////cout<<"Father\n";
    //cout<<"("<<x->leftBoundary<<", "<<x->rightBoundary<<")\n";

    if(x->leftBoundary == x->rightBoundary)
    {
        x->leftSon = NULL;
        x->rightSon = NULL;
    }
    else if(x->leftBoundary < x->rightBoundary)
    {
        interval *leftSon = new interval;
        interval *rightSon = new interval;

        int middleBoundary = (x->leftBoundary + x->rightBoundary) / 2;

        leftSon->leftBoundary = x->leftBoundary;
        leftSon->rightBoundary = middleBoundary;

        rightSon->leftBoundary = middleBoundary + 1;
        rightSon->rightBoundary = x->rightBoundary;

        x->leftSon = leftSon;
        x->rightSon = rightSon;

        //cout<<"Left son\n";
        createSons(leftSon);
        //cout<<"Right son\n";
        createSons(rightSon);
        //cout<<"End__\n";
    }
    else
    {
        cerr<<"Error! Left boundary > Right boundary\n";
    }
}

void createIntervalTree(interval *&root, int leftBoundary, int rightBoundary)
{
    root = new interval;
    root->leftBoundary = leftBoundary;
    root->rightBoundary = rightBoundary;
    createSons(root);
}

int query(interval *x, int query_leftBoundary, int query_rightBoundary)
{
    if(!x) /// NULL node reached. Is it even possible?
    {
        //cerr<<"Error! Queried node is NULL!\n";
        return 0; /// Identity element
    }

    if(x->rightBoundary < query_leftBoundary || x->leftBoundary > query_rightBoundary) /// Interval is outside query
    {
        return 0; /// Identity element
    }
    else if(x->leftBoundary >= query_leftBoundary && x->rightBoundary <= query_rightBoundary) /// Interval is inside query boundaries
    {
        return x->value;
    }
    else /// Interval partially matches the query boundaries -> query its children!
    {
        int leftSonQuery = query(x->leftSon, query_leftBoundary, query_rightBoundary);
        int rightSonQuery = query(x->rightSon, query_leftBoundary, query_rightBoundary);

        return leftSonQuery + rightSonQuery;
    }
}

void updateIndex(interval *x, int index, int value)
{
    if(!x) /// NULL node reached
        return;

    if(index < x->leftBoundary || index > x->rightBoundary) /// Index is outside interval
    {
        return;
    }
    else
    {
        x->value += value;
        updateIndex(x->leftSon, index, value);
        updateIndex(x->rightSon, index, value);
    }
}

int main()
{
    /// Variables
    interval *rootInterval;
    int n,m;

    /// Input
    in>>n>>m;
    createIntervalTree(rootInterval, 1, n);
    for(int i=0; i<n; ++i){
        int x;
        in>>x;
        updateIndex(rootInterval, i+1, x);
    }
    for(int i=0; i<m; ++i)
    {
        int a,b,caz;
        in>>caz>>a>>b;

        if(caz == 0)
            updateIndex(rootInterval, a, -b);
        else
            out<<query(rootInterval, a, b)<<"\n";
    }

    return 0;
}