Cod sursa(job #410244)

Utilizator laserbeamBalan Catalin laserbeam Data 4 martie 2010 10:53:54
Problema Arbori indexati binar Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
// Catalin Balan
// Thu Mar  4 10:11:53 EET 2010
// Infoarena - Arbori Indexati Binar

#include <cstdio>
#include <cstdlib>

using namespace std;

#define	NMAX 100
#define CHUNK 8192

#define FIN "aib.in"
#define FOUT "aib.out"

char g_buf[CHUNK];
int g_p=CHUNK-1;

inline int get()
{

	int x = 0;
	while (g_buf[g_p] < '0' || g_buf[g_p] > '9')
		if (++g_p == CHUNK) fread(g_buf,1,CHUNK,stdin), g_p=0;

	while (g_buf[g_p] >= '0' && g_buf[g_p] <= '9')
	{
		x = x*10 + g_buf[g_p]-'0';
		if (++g_p == CHUNK) fread(g_buf,1,CHUNK,stdin), g_p=0;
	}
	return x;
}

int n,a[NMAX];

void update( int poz, int val)
{
	while (poz <= n)
	{
		a[poz]	+= val;
		poz 	 = poz + ( poz & ~(poz-1) );
	}
}

int sum( int poz )
{
	int S = 0;
	while (poz)
	{
		S	+= a[poz];
		poz	 = poz - ( poz & ~(poz-1) );
	}
	return S;
}

int search( int val )
{

	int step, i;
	for (step = 1; step < n; step <<= 1);

	for (i = 0; step > 0; step >>= 1)
	{
		if (i + step > n) continue;

		if ( a[i+step] == val ) return i+step;
		if ( a[i+step] < val )
		{
			i   += step;
			val -= a[i];
		}

	}

	return -1;
}

int main(int argv, char ** argc)
{
	freopen(FIN, "r", stdin);
	freopen(FOUT, "w", stdout);

	n = get();
	int m = get();
	int type, a, b;
	for (int i = 1; i <= n; ++i)
		update(i,get());
	for (;m;--m)
	{
		type = get();
		switch(type)
		{
			case 0: { a = get(); b = get(); update(a, b); break; }
			case 1: { a = get(); b = get(); printf("%d\n", sum(b) - sum(a-1)); break; }
			case 2: { printf("%d\n", search( get() )); break; }
		}
	}
	
	return EXIT_SUCCESS;
}