Cod sursa(job #398748)

Utilizator ooctavTuchila Octavian ooctav Data 19 februarie 2010 12:01:57
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.24 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 step=1;
	
	for(;step<=N;step<<=1);
	step>>=1;
	
	for(int i=0;step;step>>=1)
		if(i+step<=N)
			if(arb[i+step]<=val)
			{
				i+=step,val-=arb[i];
				if(!val)
					return i;
			}
	return -1;
}

int suma(int x)
{
	int C=0,S=0;
	
	while(x>0)
	{
		S+=arb[x];
		while(!(x & 1<<C)) C++;
		x-=1<<C;
		C+=1;
	}
	
	return S;
}

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;
}