Cod sursa(job #1759543)

Utilizator andreioneaAndrei Onea andreionea Data 19 septembrie 2016 14:50:50
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <fstream>
#include <vector>

class AIB
{
public:
	AIB(int);
	void Insert(unsigned long long, int);
	unsigned long long GetSum(int, int) const;
	unsigned long long GetSum(int) const;
	int GetPos(unsigned long long) const;
private:
	std::vector<unsigned long long> v;
};

AIB::AIB(int n): v(n, 0) {}


void AIB::Insert(unsigned long long val, int pos)
{
	if (pos > v.size())
		return;
	v[pos - 1] += val;
	Insert(val, pos + (pos & (-pos)));
}

unsigned long long AIB::GetSum(int pos) const
{
	if (pos <= 0)
		return 0;
	if (pos == 1)
		return v[pos - 1];
	return v[pos - 1] + GetSum(pos - (pos & (-pos)));
}

unsigned long long AIB::GetSum(int posA, int posB) const
{
	unsigned long long a = GetSum(posA - 1), b = GetSum(posB);
	return b - a;
}

int AIB::GetPos(unsigned long long a) const
{
	int fst = 1;
	int lst = v.size();
	while (fst != lst) {
		auto mid = (fst + lst) / 2;
		auto sum = GetSum(mid);
		if (sum < a)
			fst = mid + 1;
		else if (sum > a)
			lst = mid - 1;
		else {
			if (fst != lst) {
				lst = mid;
			}
		}
	}
	return fst;
}

int main()
{
	int n, m;
	std::ifstream f("aib.in");
	std::ofstream g("aib.out");
	f >> n >> m;
	AIB aib(n);
	for(int i = 1; i <= n; ++i){
		long long x;
		f >> x;
		aib.Insert(x, i);
	}
	while (m--) {
		int op;
		long long a,b;
		f >> op;
		if (op == 0) {
			f >> a >> b;
			aib.Insert(b, a);
		}
		else 
		if (op == 1) {
			f >> a >> b;
			g << aib.GetSum(a, b) << "\n";
		}
		else {
			f >> a;
			g << aib.GetPos(a) << "\n";
		}
	}
	f.close();
	g.close();
	return 0;
}