Cod sursa(job #1125079)

Utilizator valiro21Valentin Rosca valiro21 Data 26 februarie 2014 15:36:45
Problema Arbori indexati binar Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.42 kb
#include <cstdio>
#include <vector>

#define NMax 100001

using namespace std;

long a, b, n, m, v[NMax];
long bl;

class treeNod {
public:
    treeNod *leftChild, *rightChild;
    long val, ia, ib;

    treeNod ( ) {
        leftChild = rightChild = NULL;
        val = ia = ib = 0;
    }

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

    long createNod ( long v[], long left, long right ) {
        ia = left; ib = right;
        if ( left == right ) {
            val = v[left];
            return v[left];
        }
        else {
            leftChild = new treeNod;
            rightChild = new treeNod;

            long middle = left + ( right - left ) / 2;
            val = leftChild->createNod ( v, left, middle ) + rightChild->createNod ( v, middle + 1, right );
            return val;
        }
    }

    long sumInter ( long left, long right ) {
        long middle = ia + ( ib - ia ) / 2;
        if ( left == ia && right == ib )
            return val;
        else if ( left <= middle && middle < right) {
            long x1 = leftChild->sumInter ( left, middle );
            long x2 = rightChild->sumInter ( middle + 1, right );
            return x1 + x2;
        }
        else if ( left <= middle && right <= middle )
            return leftChild->sumInter ( left, right );
        else
            return rightChild->sumInter ( left, right );
    }

    long addVal ( long poz, long value ) {
        if ( ia == ib && ia == poz )
            val += value;
        else {
            long middle = ia + ( ib - ia ) / 2;
            if ( poz <= middle )
                val = leftChild->addVal ( poz, value ) + rightChild->val;
            else
                val = leftChild->val + rightChild->addVal ( poz, value );
        }
        return val;
    }
};

class Tree {
public:
    treeNod *t;
    long sum;

    Tree ( ) {
        t = NULL;
        sum = 0;
    }

    void createTree ( long v[], long n ) {
        t = new treeNod;
        if ( n > 0 ) sum = t->createNod ( v, 1, n );
    }

    void addVal ( long poz, long value ) {
        sum = t->addVal ( poz, value );
    }

    long sumInter ( long left, long right ) {
        return t->sumInter ( left, right );
    }

    long findSumFromFirst ( long s ) {
        long returnVal = 0;
        treeNod *now = t;
        while ( returnVal == 0 ) {
            long middle = now->ia + ( now->ib - now->ia ) / 2;
            long S = sumInter ( 1, middle );

            if ( now->ia == now->ib )
                if ( S != s ) returnVal = -1;
                else returnVal = now->ia;
            else
                if ( S > s )
                    now = now->leftChild;
                else if ( s == S )
                    returnVal = middle;
                else
                    now = now->rightChild;
        }

        return returnVal;
    }
} tr;

int main()
{
    freopen ( "aib.in", "r", stdin );
    freopen ( "aib.out", "w", stdout );

    scanf ( "%ld %ld", &n, &m );
    for ( long i = 1; i <= n; i++ )
        scanf ( "%ld", &v[i] );

    tr.createTree ( v, n );
    for ( long i = 1; i <= m; i++ ) {
        scanf ( "%ld", &bl );

        if ( bl < 2 ) {
            scanf ( "%ld %ld", &a, &b );
            if ( bl == 1 )
                printf ( "%ld\n", tr.sumInter ( a, b ) );
            else
                tr.addVal ( a, b );
        }
        else
            scanf ( "%ld", &a ),
            printf ( "%ld\n", tr.findSumFromFirst ( a ) );
    }

    return 0;
}