Cod sursa(job #530956)

Utilizator Gaby_mMititelu Gabriel Gaby_m Data 8 februarie 2011 18:35:51
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include<cstdio>
using namespace std;

#define NMAX 100001

int a[NMAX];
int aib[NMAX];
int N;

int indx(int val) {
	return (val ^ (val-1)) & val;
}

void buildAIB() {
	int i;
	aib[1] = a[1];
	for (i = 2; i <= N; i++) {
		aib[i] = aib[i-1] + a[i];
	}

 	for (i = N; i > 1; i--) {
		aib[i] = aib[i] - aib[i-indx(i)];
	}
}

void addValue(int val, int poz) {
	for( int i = poz; i <= N; i+= indx(i)) {
		aib[i] += val;
	}
}

int getSum(int poz) {
	int sum = 0;
	for (int i = poz; i > 0; i-= indx(i)) {
		sum += aib[i];
	}
	return sum;
}


int getPoz(int val)
{
    int i, step;    
    for ( step = 1; step < N; step <<= 1 );     
    for( i = 0; step; step >>= 1 )
    {
         if( i + step <= N)
         {
            if( val >= aib[i+step] ) 
            {
                i += step, val -= aib[i];
                if ( !val ) return i;
            }
         }
    }
    
    return -1;
}

int main() {
	freopen("aib.in", "r", stdin);
	freopen("aib.out", "w", stdout);
	int M;
	scanf("%d %d", &N, &M);
	int i;
	for (i = 1; i <= N; i++) {
		scanf("%d ", &a[i]);
	}

	buildAIB();

	int op, x, y;
	for (i = 0; i < M; i++) {
		scanf("%d", &op);
		
		switch (op){
		case 0: {
			scanf("%d %d", &x, &y);
			addValue(y, x);
			break;
				}
		case 1: {
			scanf("%d %d", &x, &y);
			printf("%d\n", getSum(y) - getSum(x-1));
			break;
				}
		case 2: {
			scanf("%d", &x);
			printf("%d\n", getPoz(x));
			break;
				}
		default: break;
		}
	}



	return 0;
}