Cod sursa(job #779934)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 19 august 2012 03:25:14
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb

#include <cstdio>

const unsigned int MAX_LENGTH(100001);
unsigned int bit [MAX_LENGTH];
unsigned int length;

inline void bit_update (unsigned int index, unsigned int value)
{
	unsigned int power(1);
	while (index <= length)
	{
		while (!(index & power))
			power <<= 1;
		bit[index] += value;
		index += power;
		power <<= 1;
	}
}

inline unsigned int bit_sum (unsigned int index)
{
	unsigned int sum(0), power(1);
	while (index)
	{
		while (!(index & power))
			power <<= 1;
		sum += bit[index];
		index -= power;
		power <<= 1;
	}
	return sum;
}

inline signed int bit_search_sum (unsigned int value)
{
	signed int left(0), right(length + 1), middle(length), best(right);
	unsigned int sum;
	if (bit_sum(middle) == value)
		best = middle;
	while (middle)
	{
		middle = (left + right) >> 1;
		sum = bit_sum(middle);
		if (value < sum)
		{
			if (right > middle)
				right = middle;
			--middle;
		}
		else if (value > sum)
		{
			if (left < middle)
				left = middle;
			++middle;
		}
		else
		{
			if (best > middle)
				best = middle;
			right = middle;
			--middle;
		}
		if (middle <= left || middle >= right)
			break;
	}
	if (best > length)
		return -1;
	return best;
}

int main (void)
{
	unsigned int m;
	std::freopen("aib.in","r",stdin);
	std::freopen("aib.out","w",stdout);
	std::scanf("%u%u",&length,&m);
	unsigned int a, *a_ptr(&a);
	for (unsigned int counter(1) ; counter <= length ; ++counter)
	{
		std::scanf("%u",a_ptr);
		bit_update(counter,a);
	}
	std::scanf("\n");
	char option;
	unsigned int b, *b_ptr(&b);
	do
	{
		option = std::getchar();
		std::scanf("%u",a_ptr);
		if (option < '2')
		{
			std::scanf("%u",b_ptr);
			if (option == '0')
				bit_update(a,b);
			else
				std::printf("%u\n",bit_sum(b) - bit_sum(a - 1));
		}
		else
			std::printf("%d\n",bit_search_sum(a));
		std::getchar();
		--m;
	}
	while (m);
	std::fclose(stdin);
	std::fclose(stdout);
	return 0;
}