Cod sursa(job #1687600)

Utilizator howsiweiHow Si Wei howsiwei Data 12 aprilie 2016 22:48:46
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

int n;

template<typename T, typename F>
void init(F f, vector<T>& t) {
	for (int i = n-1; i >= 1; i--) {
		t[i] = f(t[2*i], t[2*i+1]);
	}
}

template<typename T, typename F>
void update(F f, vector<T>& t, T x, int i) {
	i += n;
	while (i >= 1 && t[i] != x) {
		t[i] = x;
		x = f(t[(i|1)^1], t[i|1]);
		i /= 2;
	}
}

template<typename T, typename F>
T query(T id, F f, const vector<T>& t, int l, int r) {
	l += n;
	r += n-1;
	T c0 = id;
	T c1 = id;
	while (l < r) {
		if (l%2 == 0) {
			l = l/2;
		} else {
			c0 = f(c0, t[l]);
			l = l/2+1;
		}
		if (r%2 == 1) {
			r = r/2;
		} else {
			c1 = f(t[r], c1);
			r = r/2-1;
		}
	}
	if (l == r) {
		c0 = f(c0, t[l]);
	}
	return f(c0, c1);
}

template<typename T, typename F>
int index(T c, F f, const vector<T>& t, T b, int l) {
	l += n;
	int h = 0;
	while (l+1<<h <= 2*n && f(c, t[l]) <= b) {
		// printf("l: %d h: %d\n", l, h);
		if (l%2 == 0) {
			l = l/2;
		} else {
			c = f(c, t[l]);
			l = l/2+1;
		}
		h++;
	}
	// puts("");
	while (true) {
		do {
			// printf("l: %d h: %d\n", l, h);
			l = l*2;
			h--;
		} while (h >= 0 && !(l+1<<h <= 2*n && f(c, t[l]) <= b));
		// puts("");
		if (h < 0) return l/2-n;
		c = f(c, t[l]);
		l++;
	}
}

int main() {
#ifdef INFOARENA
	freopen("aib.in", "r", stdin);
	freopen("aib.out", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	::n = n;
	vector<int> t(2*n);
	for (int i = 0; i < n; i++) {
		cin >> t[i+n];
	}
	init(plus<int>(), t);
	int op, idx, lo, hi, val;
	for (int i = 0; i < m; ++i) {
		cin >> op;
		if (op == 0) {
			cin >> idx >> val;
			idx--;
			// bit.update(idx, val);
			update(plus<int>(), t, val, idx);
		}
		else if (op == 1) {
			cin >> lo >> hi;
			lo--;
			// printf("%d\n", bit.getsum(lo, hi));
			printf("%d\n", query(0, plus<int>(), t, lo, hi));
		}
		else if (op == 2) {
			cin >> val;
			// printf("%d\n", bit.idx_of_sum(val));
			printf("%d\n", index(0, plus<int>(), t, val, 0));
		}
	}

}