Cod sursa(job #903484)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 1 martie 2013 21:16:28
Problema Arbori indexati binar Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb

#include <cstdio>

const int MAX_N(100001);

int n, m;

int bit [MAX_N];

inline int lsb (int x)
{
	return x & (-x);
}

inline void update (int p, int v)
{
	bit[p] += v;
	p += lsb(p);
	while (p <= n)
	{
		bit[p] += v;
		p += lsb(p);
	}
}

inline int query (int p)
{
	int sum(bit[p]);
	p -= lsb(p);
	while (p)
	{
		sum += bit[p];
		p -= lsb(p);
	}
	return sum;
}

inline int search (int x)
{
	int left(1), right(n), middle((left + right) >> 1), sum;
	while (left < right)
	{
		sum = query(middle);
		if (sum > x)
			right = middle - 1;
		else if (sum < x)
			left = middle + 1;
		else
			break;
		middle = (right + left) >> 1;
	}
	if (query(middle) == x)
		return middle;
	return -1;
}

inline void read (void)
{
	std::scanf("%d %d\n",&n,&m);
	int x;
	for (int i(1) ; i <= n ; ++i)
	{
		std::scanf("%d",&x);
		update(i,x);
	}
}

int main (void)
{
	std::freopen("aib.in","r",stdin);
	std::freopen("aib.out","w",stdout);
	read();
	int o, a, b;
	while (m)
	{
		std::scanf("%d",&o);
		if (o == 2)
		{
			std::scanf("%d",&a);
			std::printf("%d\n",search(a));
		}
		else if (o == 1)
		{
			std::scanf("%d %d",&a,&b);
			std::printf("%d\n",query(b) - query(a - 1));
		}
		else
		{
			std::scanf("%d %d",&a,&b);
			update(a,b);
		}
		--m;
	}
	std::fclose(stdout);
	std::fclose(stdin);
	return 0;
}