Cod sursa(job #385049)

Utilizator ooctavTuchila Octavian ooctav Data 21 ianuarie 2010 23:56:58
Problema Arbori indexati binar Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <cstdio>
#define NMAX 100001
int N,M;
int e[NMAX];
void citire();
void schimbare();
void suma();
void pozitie();
int put(int a);
int interval(int a);

int main()
{
	int iden;
	freopen("aib.in","r",stdin);
	freopen("aib.out","w",stdout);
	citire();

	
	for(int i=1;i<=M;i++)
	{
		scanf("%d",&iden);
		if(iden==0)
			schimbare();
		else if(iden==1)
			suma();
		else
			pozitie();		
	}
	
	return 0;
}

void citire()
{
	int x,i2;
	scanf("%d %d",&N,&M);
	for(int i=1;i<=N;i++)
	{
		scanf("%d",&x);
		i2=i;
		while(i2<=N)
		{
			e[i2]=e[i2]+x;
			i2=i2+put(i2);
		}		
	}
}

void schimbare()
{
	int a,b;
	scanf("%d %d",&a,&b);
	while(a<=N)
	{
		e[a]=e[a]+b;
		a=a+put(a);
	}
		
}

void suma()
{
	int a,b;
	scanf("%d %d",&a,&b);
	printf("%d\n",interval(b)-interval(a-1));
}

void pozitie()
{
	int a,k=0,p=1,val;
	scanf("%d",&a);
	while(p<=N)
		p=p<<1;
	p=p>>1;
	while(p)
	{
		val=interval(k+p);
		if(val==a)
		{
			printf("%d\n",k+p);
			return;
		}
		else if(val<a)
			k=k+p;
		p=p>>1;
	}
	printf("-1\n");
}

int interval(int a)
{
	int s=0,p=put(a);
	while(a)
	{
		s=s+e[a];
		a=a-p;
		p=put(a);
	}
	return s;
}

int put(int a)
{
	int nr=0,p=1;
	while(a && a%2==0)
	{
		a=a/2;
		nr++;
	}
	while(nr--)
		p=p<<1;
	
	return p;
}