Cod sursa(job #1420223)

Utilizator alexandru94hahahalera alexandru94 Data 17 aprilie 2015 22:48:28
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>

using namespace std;

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

// pe pozitiile respective se adauga valoarea val
inline void insert_aib(vector<int> &aib, int idx, int val) {
	for(int i = idx; i < aib.size(); i += least_significant_bit(i))
	{
		aib[i] += val;
	}
}

// aduna elementele in  intervalul (0 idx]
inline int sum(vector<int> &aib, int idx) {
	int sum = 0;
	for(int i = idx; i > 0; i -= least_significant_bit(i)) {
		sum += aib[i];
	}
	return sum;
}

// cauta intervalul [0, i] care are suma val
inline int search(vector<int> &aib, int val) {
	// caut cea mai mica putere a lui 2 mai mare decat N = aib.size()
	int pas = (1 << 30);
	for(int i = 0; pas; pas = (pas >> 1)) {
		if(i + pas <= (signed)aib.size() && aib[i + pas] <= val) {
			i += pas;
			val -= aib[i];
			
			if(val == 0) {
				return i;
			}
		}
	}
	return -1;
}

int main()
{
	ifstream in("aib.in");
	ofstream out("aib.out");
	int N, M;
	vector<int> aib; //reprezint arborele idexat binar
	int val, poz;
	
	in >> N >> M;
	for(int i = 0; i < N; i++) {
		in >> val >> poz;
		insert_aib(aib, poz, val);
	}
	
	for(int i = 0; i < M; i++) {
		int operatie, a, b;
		in >> operatie;
		switch(operatie) {
			case 0:
				in >> poz >> val;
				insert_aib(aib, poz, val);
				break;
			case 1:
				in >> a >> b;
				out << sum(aib, b) - sum(aib, a - 1) << "\n";
				break;
			case 2:
				in >> val;
				out << search(aib, val) << "\n";
				break;
		}
	}
	
	in.close();
	out.close();
}