Cod sursa(job #1390522)

Utilizator johnyJohny Deep johny Data 17 martie 2015 09:16:07
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
/* Aplicatie la Arbori Indexati Binar
- determinarea sumei pe un interval si update-uri la elemente */

#include <fstream>

#define NMAX 100005
// formula pentru cel mai nesemnificativ bit de 1 al lui x
#define LSB(x) ( (-x)&x )

using namespace std;

ifstream fin("aib.in");
ofstream fout("aib.out");

int N, M, i, AIB[NMAX], Tip, a, b, X;

inline void Update( int Valoare, int Pos )
{ // aduna valoare la elementul de pe pozitia Pos
    for( int i = Pos; i <= N; i += LSB(i) )
 // se updateaza toate intervalele care contin elementul de la pozitia data
        AIB[i] += Valoare;
}

inline int suma( int Pos )
{
    int S = 0;

    for( int i = Pos; i > 0; i -= LSB(i) )
    // se face suma pe interval
        S += AIB[i];

    return S;
}

inline int SumaInterval( int a, int b )
{
    return ( suma(b) - suma(a-1) );
}

inline int SumaMin(int a)
{
    int i;
    while(SumaInterval(1,i)<a && i<=N)
        i++;
    if(SumaInterval(1,i)==a)
        return i;
    else
        return -1;
}

int main()
{
    fin >> N >> M;
    for( i = 1; i <= N; i++ )
    {
        fin >> X;
    // se updateaza arborele pentru fiecare element introdus in sir
        Update( X, i );
    }

    while( M-- )
    {
        fin >> Tip;

        switch( Tip )
        {
            case 0: // operatia de tip 0: se adauga la elementul de pe pozitia a valoarea b
                fin >> a >> b;
                Update( b, a );
                break;
            case 1: // operatia de tip 1: se determina suma pe intervalul [a,b]
                fin >> a >> b;
                fout << SumaInterval( a, b ) << '\n';
                break;
            case 2: // operatia de tip 2: se determina un interval [1,b] cu suma a,
                    // sau -1, daca nu exista intervalul
                fin>>a;
                fout<<SumaMin(a)<<'\n';
                break;
        }
    }

    return 0;
}