Cod sursa(job #1751878)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 2 septembrie 2016 11:14:59
Problema Arbori indexati binar Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <fstream>
#include <queue>

using namespace std;

int* ReadList(int n, istream &fin);
int* CreateBit(int n, int* list);

int* ReadList(int n, istream &fin);
int* CreateBit(int n, int* list);
void ApplyQuerys(int n, int m, int* tree, istream &fin, ostream &fout);
void ChangeElem(int n, int a, int b, int *tree);
int SumElem(int a, int b, int *tree);
int GetSum(int a, int* tree);
int DetPos(int n, int a, int *tree);

int main()
{
	ifstream fin;
	ofstream fout;
	fout.open("aib.out");
	fin.open("aib.in");

	int n, m;
	fin >> n >> m;

	int* list = ReadList(n, fin);
	int* tree = CreateBit(n, list);
	ApplyQuerys(n, m, tree, fin, fout);

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

int* ReadList(int n, istream &fin)
{
	int *list = new int[n + 1]();

	for(int i = 1; i <= n; i++)
	{
		fin >> list[i];
	}

	return list;
}

int* CreateBit(int n, int* list)
{
	int *tree = new int[n + 1]();

	for(int i = 1; i <= n; i++)
	{
		int r = 0;
		while(((1 << r) & i) == 0)
		{
			r ++;
		}

		for(int j = i - (1 << r) + 1; j <= i; j++)
		{
			tree[i] += list[j];
		}
	}

	return tree;
}

void ApplyQuerys(int n, int m, int* tree, istream &fin, ostream &fout)
{
	int opt, a, b;

	for(int i = 1; i <= m; i++)
	{
		fin >> opt;
		switch(opt)
		{
			case 0:
				fin >> a >> b;
				ChangeElem(n, a, b, tree);
				break;
			case 1:
				fin >> a >> b;
				fout << SumElem(a, b, tree) << '\n';
				break;
			case 2:
				fin >> a;
				fout << DetPos(n, a, tree) << '\n';
				break;
			default:
				exit(1);
		}
	}
}

void ChangeElem(int n, int a, int b, int *tree)
{
	while(a <= n)
	{
		tree[a] += b;
		a += (a & (-1)*a);
	}
}

int SumElem(int a, int b, int *tree)
{
	return GetSum(b, tree) - GetSum(a - 1, tree);
}

int GetSum(int a, int* tree)
{
	int sum = 0;

	while(a > 0)
	{
		sum += tree[a];
		a -= (a & (-1)*a);
	}

	return sum;
}

int DetPos(int n, int a, int *tree)
{
	int r = 0;

	while((1 << r) <= n)
	{
		r++;
	}
	r--;

	int idx = 0;
	int bitMask = (1 << r);

	while(bitMask > 0 && idx < n)
	{
		int tmp = idx + bitMask;

		if(a == tree[tmp])
		{
			return tmp;
		}
		else if(a > tree[tmp])
		{
			idx = tmp;
			a -= tree[tmp];
		}

		bitMask >>= 1;
	}

	if(a != 0)
	{
		return -1;
	}

	return idx;
}