Cod sursa(job #2206095)

Utilizator whoiscrisCristian Plop whoiscris Data 21 mai 2018 01:48:10
Problema Arbori indexati binar Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.46 kb
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;

class BIT {

public:

	vector<int> arr;
	int size;
	int max_stepsize;

	BIT(int n) {
		arr.resize(n+1);	// we start at index 1 .. n
		size = arr.size();

		max_stepsize = 1;
		while (max_stepsize < size) {
			max_stepsize <<= 1;
		}
	}


	void update (int i, int delta) {
		for (; i < size; i += (i & -i)) {
			arr[i] += delta;
		}
	}

	// computes prefix sum at [1 .. i]
	int prefix_sum (int i) {
		int sum = 0;
		for (; i>0; i -= (i & -i)) {
			sum += arr[i];
		}
		return sum;
	}

	// computes range sum at [i .. j]
	int range_sum (int& i, int& j) {
		return prefix_sum(j) - prefix_sum(i-1);
	}

	int min_k (int a) {
		// we need to do the binary search directly on the bit.
		int k = 0;
		int j;
		for (int step_size = max_stepsize; step_size > 0; step_size >>= 1) {
			j = k+step_size;
			if (j < size && arr[j] <= a) {
				a -= arr[j];
				k += step_size;
			}

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


int main () {

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

	int n,m;
	cin >> n >> m;
	BIT bit(n);
	int val, c, a, b;
	for (int i=0; i<n; ++i) {
		cin >> val;
		bit.update(i+1, val);
	}

	for (int i=0; i<m; ++i) {
		cin >> c;

		if (c == 0) {
			cin >> a >> b;
			bit.update(a,b);
		}
		else if (c == 1) {
			cin >> a >> b;
			cout << bit.range_sum(a,b) << endl;
		}
		else {
			cin >> a;
			cout << bit.min_k(a) << endl;
		}
	}

	return 0;
}