Cod sursa(job #2042389)

Utilizator andreigasparoviciAndrei Gasparovici andreigasparovici Data 18 octombrie 2017 16:00:12
Problema Arbori indexati binar Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>
using namespace std;

#define NMAX 100005

class AIB {
	inline int zero(int x) { return (x ^ (x - 1)) & x; }

	int aib[NMAX], n;

	public:
		AIB(int size);
		int getSize();
		void update(int position, int value);
		int query(int position);
};

AIB::AIB(int size) {
	n = size;
	fill(aib, aib + n + 1, 0);
}

int AIB::getSize() {
	return n;
}

void AIB::update(int position, int value) {
	for(int i = position; i <= n; i += zero(i))
		aib[i] += value;
}

int AIB::query(int position) {
	int result = 0;
	for(int i = position; i > 0; i -= zero(i))
		result += aib[i];
	return result;
}

int binSearch(AIB aib, int sum) {
	int left = 1, right = aib.getSize();

	while(left <= right) {
		int middle = (left + right) / 2;
		int result = aib.query(middle);

		if(result == sum)
			return middle;
		if(result > sum) 
			right = middle - 1;
		else left = middle + 1;
	}

	return -1;
}

int N, Q;

int main() {
	freopen("aib.in", "r", stdin);
	freopen("aib.out", "w", stdout);

	scanf("%d %d ", &N, &Q);	

	AIB arbore(N);

	for(int i = 1; i <= N; i++) {
		int item;
		scanf("%d ", &item);
		arbore.update(i, item);
	}

	for(int q = 1; q <= Q; q++) {
		int operation;
		scanf("%d ", &operation);

		if(operation == 0) {
			int position, value;
			scanf("%d %d ", &position, &value);
			arbore.update(position, value);
		}
		else if(operation == 1) {
			int left, right;
			scanf("%d %d ", &left, &right);
			int result = arbore.query(right) - arbore.query(left - 1);
			printf("%d\n", result);
		}
		else if(operation == 2) {
			int sum;
			scanf("%d ", &sum);
			int position = binSearch(arbore, sum);
			printf("%d\n", position);
		}
	}

	return 0;
}