Cod sursa(job #2819346)

Utilizator teodorescunicolasteodorescu nicolas alexandru teodorescunicolas Data 18 decembrie 2021 11:32:09
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 kb
#include <stdio.h>

#define NMAXX 100000
#define LOGN 16

using namespace std;

int v[NMAXX + 1], aib[NMAXX + 1];

int lastSignificantBit( int x ) {
    return x & -x;
}

void build( int n ) {
    int i;

    for ( i = 1; i <= n; i++ ) {
        aib[i] += v[i];
        if ( i + lastSignificantBit( i ) <= n )
            aib[i + lastSignificantBit( i )] += aib[i];
    }
}

void update( int poz, int val, int n ) {
    while ( poz <= n ) {
        aib[poz] += val;
        poz += lastSignificantBit( poz );
    }
}

int query( int x ) {
    int rez;

    rez = 0;
    while ( x > 0 ) {
        rez += aib[x];
        x -= lastSignificantBit( x );
    }

    return rez;
}

int search( int val, int n ) {
    int poz, step, suma;

    suma = poz = 0;
    step = 1 << LOGN;
    while ( step > 0 ) {
        if ( poz + step <= n && suma + aib[poz + step] <= val ) {
            poz += step;
            suma += aib[poz];
        }

        step >>= 1;
    }

    if ( suma != val || poz == 0 )
        poz = -1;

    return poz;
}

int main()
{
    FILE *fin, *fout;
    int n, m, i, cer, a, b;

    fin = fopen( "aib.in", "r" );
    fout = fopen( "aib.out", "w" );

    fscanf( fin, "%d%d", &n, &m );
    for ( i = 1; i <= n; i++ )
        fscanf( fin, "%d", &v[i] );

    build( n );

    for ( i = 0; i < m; i++ ) {
        fscanf( fin, "%d", &cer );

        if ( cer == 0 ) {
            fscanf( fin, "%d%d", &a, &b );
            update( a, b, n );
        } else if ( cer == 1 ) {
            fscanf( fin, "%d%d", &a, &b );
            fprintf( fout, "%d\n", query( b ) - query( a - 1 ) );
        } else {
            fscanf( fin, "%d", &a );
            fprintf( fout, "%d\n", search( a, n ) );
        }
    }

    fclose( fin );
    fclose( fout );
    return 0;
}