Cod sursa(job #1179122)

Utilizator sorin2kSorin Nutu sorin2k Data 28 aprilie 2014 00:21:56
Problema Arbori indexati binar Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.26 kb
#include<fstream>
using namespace std;

ifstream fin("aib.in");
ofstream fout("aib.out");

int aib[100001], n, m, i, opt, a, b;

int nr_de_0(int x) {
	int nr = 0;
	while(x % 2 == 0) {
		x /= 2;
		nr++;
	}
	return nr;
}

int pow_doi(int exp) {
	int rez = 1, i;
	for(i = 1; i <= exp; i++) {
		rez *= 2;
	}
	return rez;
}

void add(int poz, int val) {
	do {
		aib[poz] += val;
		poz += pow_doi(nr_de_0(poz));
	} while(poz <= n);
}

int suma(int end) {
	int sum = 0;
	do {
		sum += aib[end];
		end -= pow_doi(nr_de_0(end));
	} while(end >= 1);
	return sum;
}

int poz_min(int S) {
	int sum = 0, nr = 1, poz, ans;

	while(nr <= n) nr *= 2;
	nr /= 2;

	poz = nr;
	while(nr > 0) {
		nr /= 2;
		if(sum + aib[poz] <= S) {
			if(poz + nr <= n) {
				ans = poz;
				sum += aib[poz];
				poz += nr;
			}
		} else {
			poz -= nr;
		}
	}
	if(sum == S) return ans;
	return -1;
}

int main() {
	fin >> n >> m;
	for(i = 1; i <= n; i++) {
		fin >> a;
		add(i, a);
	}
	for(i = 0; i < m; i++) {
		fin >> opt;
		if(opt == 0) {
			fin >> a >> b;
			add(a, b);
		}
		if(opt == 1) {
			fin >> a >> b;
			fout << suma(b) - suma(a-1) << "\n";
		}
		if(opt == 2) {
			fin >> a;
			fout << poz_min(a) << "\n";
		}
	}
	return 0;
}