Cod sursa(job #794741)

Utilizator MtkMarianHagrSnaf MtkMarian Data 6 octombrie 2012 22:26:10
Problema Arbori indexati binar Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include<cstdio>
#include<cmath>
using namespace std;
#define NMAX 100005

int n, m,t,a,b,x,c[NMAX]={0},nr;


void modifica(int ,int );
int suma(int ,int );
int pozitia(int );


int main()
{
	freopen("aib.in","r",stdin);
	freopen("aib.out","w",stdout);
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&x);
		modifica(i,x);

	}

	
	
	for(int i=1;i<=m;++i)
	{
		scanf("%d ",&t);
		switch(t)
		{
		case 0: 
			scanf("%d %d",&a,&b);
			modifica(a,b);
			break;
		case 1 :
			scanf("%d %d",&a,&b);
			x=suma(a,b);
			printf("%d\n",x);
			break;
		case 2:
			scanf("%d",&a);
		   x=pozitia(a);//pozitia minima k astfel incat  suma valorilor primilor k termeni sa fie a
		 printf("%d\n",x);
		}
	}
	return 0;
}
void modifica(int poz,int val)
{
	nr=0;
	
	while(poz<=n)
	{
	c[poz]+=val;
	while(!(poz&(1<<nr)))++nr;				
	poz+=(1<<nr);
	++nr;
	}
		

}
int suma(int left,int right)
{
	int sumdr=0,sumst=0;
	while(right>0)
	{
		sumdr+=c[right];
		nr=0;
		while(!(right&(1<<nr)))++nr;
		right-=(1<<nr);
	}
	left=left-1;
	while(left>0)
	{
		sumst+=c[left];
		nr=0;
		while(!(left&(1<<nr)))++nr;
		left-=(1<<nr);
	}
	return(sumdr-sumst);
}
int pozitia(int sum)
{
	x=1;
	while(x<=n)x=x<<1;
	
	for(int i=0;x;x=(x>>1))
	{
		if(x+i<=n)
		{
			if(sum>=c[i+x])
			{
				sum-=c[i+x];
				i+=x;
			}
			if(sum==0)return i;
		}
	}
	return -1;
}