Cod sursa(job #1999280)

Utilizator Ionut.popescuLiviu Rebreanu Ionut.popescu Data 10 iulie 2017 19:52:07
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#ifdef __GNUC__
#pragma GCC target("sse4,avx")
#endif
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

template<typename T>
class FenwickTree {
private:
	vector<T> tree;

	T queryPrefix(int idx) const {
		T sum = 0;
		while (idx >= 0) {
			sum += tree[idx];
			idx = (idx & (idx + 1)) - 1;
		}
		return sum;
	}
public:
	FenwickTree(const int n = 0) : tree(n) {
	}

	FenwickTree(const vector<T>& v): tree(v.size()) {
		for (int i = 0; i < (int)tree.size(); ++i) {
			tree[i] += v[i];
			const int j = i | (i + 1);
			if (j < (int)tree.size()) {
				tree[j] += tree[i];
			}
		}
	}

	void add(int idx, const T& value) {
		while (idx < (int)tree.size()) {
			tree[idx] += value;
			idx |= idx + 1;
		}
	}

	T query(int lo, int hi) const {
		return queryPrefix(hi) - queryPrefix(lo - 1);
	}

	T getValue(int idx) const {
		T value = tree[idx];
		const int parent = (idx & (idx + 1)) - 1;
		idx--;
		while (idx != parent) {
			value -= tree[idx];
			idx = (idx & (idx + 1)) - 1;
		}
		return value;
	}

	static int binaryLogarithm(int n) {
		return 31 - __builtin_clz(n);
	}

	int lowerBound(T value) const {
		value -= 1;
		int idx = -1;
		for (int i = 1 << binaryLogarithm(tree.size()); i > 0; i >>= 1) {
			if (i + idx < (int)tree.size() && value >= tree[i + idx]) {
				value -= tree[i + idx];
				idx += i;
			}
		}
		return idx + 1;
	}
};

int main() {
#ifdef INFOARENA
	ifstream cin("aib.in");
	ofstream cout("aib.out");
#endif
	int n, q; cin >> n >> q;
	vector<int> a(n);
	for (int& x: a) {
		cin >> x;
	}

	FenwickTree<int> tree(a);
	while (q--> 0) {
		int op_type; cin >> op_type;
		if (op_type == 0) {
			int idx, value; cin >> idx >> value; idx--;
			tree.add(idx, value);
		} else if (op_type == 1) {
			int idx0, idx1; cin >> idx0 >> idx1; idx0--; idx1--;
			cout << tree.query(idx0, idx1) << '\n';
		} else {
			int sum; cin >> sum;
			cout << tree.lowerBound(sum) + 1 << '\n';
		}
	}
	return 0;
}