Cod sursa(job #651894)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 22 decembrie 2011 07:01:15
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <fstream>
#include <iostream>

#define MAXN 100002

using namespace std;

typedef unsigned int uint32;

template<typename T, int maxsize>
class BinaryIndexedTree
{
public:
	BinaryIndexedTree()
	{}
	
	inline void Update(uint32 pos, const T val)
	{
		while (pos <= m_uSize)
		{
			tree[pos] += val;
			pos += (pos & -pos);
		}
	}

	inline T Query(uint32 pos) const
	{
		T sum = 0;
		
		while (pos > 0)
		{
			sum += tree[pos];
			pos -= (pos & -pos);
		}
		
		return sum;
	}
	
	inline uint32 Search(T sum) const
	{
		uint32 step=1, i;
		
		while (step <= m_uSize)
			step <<= 1;
		
		for (i=0; step; step >>= 1)
		{
			if (i+step <= m_uSize && tree[i+step] <= sum)
			{
				i += step;
				sum -= tree[i];
				
				if (!sum)
					return i;
			}
		}
		
		return 0;
	}
	
	inline void SetSize(const uint32 size)
	{
		m_uSize = size;
	}

private:
	T tree[maxsize];
	uint32 m_uSize;
};

BinaryIndexedTree<uint32, MAXN> bitTree;

int main()
{
	uint32 n,m;
	fstream fin("aib.in", fstream::in);
	fstream fout("aib.out", fstream::out);
	
	
	fin >> n >> m;
	//cout << n << " " << m << endl;
	
	bitTree.SetSize(n);
	
	for (uint32 i=1; i<=n; ++i)
	{
		uint32 x;
		fin >> x;
		
		bitTree.Update(i, x);
	}
	
	for (uint32 i=0; i<m; ++i)
	{
		uint32 opt, a, b, k, sum;
		fin >> opt;
		
		switch (opt)
		{
			case 0:
			{
				fin >> a >> b;
				bitTree.Update(a,b);
			}; break;
			
			case 1:
			{
				fin >> a >> b;
				
				fout << bitTree.Query(b) - bitTree.Query(a-1) << "\n";
			}; break;
			
			case 2:
			{
				fin >> sum;
				k = bitTree.Search(sum);
				
				if (k)
				{
					fout << k << "\n";
				}
				else
				{
					fout << -1 << "\n";
				}
			}; break;
		}
	}

	fin.close();
	fout.close();
	return 0;
}