Cod sursa(job #398734)

Utilizator ooctavTuchila Octavian ooctav Data 19 februarie 2010 11:33:07
Problema Arbori indexati binar Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.27 kb
#include <cstdio>
#define in "aib.in"
#define out "aib.out"
#define NMAX 100001

int cauta(int val);
int suma(int x1);
void adauga(int poz,int val);

int N,M;
int arb[NMAX];

void citire()
{
	int val,a,x1,x2,poz;
	scanf("%d %d",&N,&M);
	for(int i=1;i<=N;i++)
	{
		scanf("%d",&val);
		adauga(i,val);
	}
	for(int i=1;i<=M;i++)
	{
		scanf("%d",&a);
		if(a==0)
		{
			scanf("%d %d",&poz,&val);
			adauga(poz,val);
		}
		else if(a==1)
		{
			scanf("%d %d",&x1,&x2);
			printf("%d\n",suma(x2)-suma(x1-1));
		}
		else
		{
			scanf("%d",&val);
			printf("%d\n",cauta(val));
		}
	}
}

int cauta(int val)
{
	int P=1,poz=0;
	while(P<=N)
		P<<=1;
	P>>=1;
	
	while(P)
	{
		if(arb[poz+P]<=val)
		{
			poz+=P;
			val-=arb[poz];
		}
		if(!val)
			return poz;
		P>>=1;
	}
		
	return -1;
}

int suma(int x)
{
	int P=1,suma=0,poz=0;
	while(P<=x)
		P<<=1;
	P>>=1;
	
	while(P)
	{
		if(poz+P<=x)
		{
			poz+=P;
			suma+=arb[poz];
		}
		P>>=1;
	}
	
	return suma;
}

void adauga(int poz,int val)
{
	int C = 0;
	while ( poz <= N )
	{
	   arb[poz] += val;
	   while ( !(poz & (1<<C)) ) C++;
	   poz += (1<<C);
	   C += 1;
	}

}

int main()
{
	freopen(in,"r",stdin);
	freopen(out,"w",stdout);
	citire();
	
	return 0;
}