Cod sursa(job #2739361)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 7 aprilie 2021 21:03:58
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.62 kb
#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
#define Test(tt) cout << "Case #" << tt << ": "
 
 
using namespace std;

template<typename T,
		 typename Func = std::function<T(const T&, const T&)>,
		 typename Alloc = std::vector<T>>
class Fenwick {
public:
	Fenwick() {}
	Fenwick(int n) : n(n) {
		combine = [](const T& a, const T& b) { return a + b; };
		data.resize(n + 1);
	}
	Fenwick(int n, Func func) : n(n) {
		combine = func;
		data.resize(n + 1);
	}
	~Fenwick() {
		data.clear();
	}

	void init(int _n, const T& t = T()) {
		n = _n;
		data.resize(n + 1, t);
	}
	void set(const T& t) {
		fill(data.begin(), data.end(), t);
	}
	T get(int pos) {
		return data[pos];
	}

	void update_prefix(int pos, const T& t) {
		for (int i = pos; i <= n; i += lsb(i)) {
			data[i] = std::move(combine(data[i], t));
		}
	}
	void update_suffix(int pos, const T& t) {
		for (int i = pos; i > 0; i -= lsb(i)) {
			data[i] = std::move(combine(data[i], t));
		}
	}

	T query_prefix(int pos) {
		T answer{};
		for (int i = pos; i > 0; i -= lsb(i)) {
			answer = std::move(combine(answer, data[i]));
		}
		return answer;
	}
	T query_suffix(int pos) {
		T answer{};
		for (int i = pos; i <= n; i += lsb(i)) {
			answer = std::move(combine(answer, data[i]));
		}
		return answer;
	}

private:
	Alloc data;
	Func combine;
	int n;
};


int main() {
#ifdef HOME
    ifstream cin("A.in");
    ofstream cout("A.out");
#endif
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

#ifndef HOME
    ifstream cin("aib.in");
    ofstream cout("aib.out");
#endif

    int n, m;
    cin >> n >> m;

    auto comb = [](const ll& a, const ll& b) -> ll { return a + b; };
    Fenwick<ll> fen(n, comb);

    for (int i = 1; i <= n; i++) {
    	int x;
    	cin >> x;
    	fen.update_prefix(i, x);
    }

    while (m--) {
    	int t;
    	cin >> t;
    	if (t == 0) {
    		int a, b;
    		cin >> a >> b;
    		fen.update_prefix(a, b);
    	}
    	if (t == 1) {
    		int a, b;
    		cin >> a >> b;
    		cout << fen.query_prefix(b) - fen.query_prefix(a - 1) << "\n";
    	}
    	if (t == 2) {
    		ll a, sum = 0;
    		cin >> a;
    		int res = 0;
    		for (int step = 1 << 17; step; step >>= 1) {
    			if (res + step <= n && sum + fen.get(res + step) < a) {
    				res += step;
    				sum += fen.get(res);
    			}
    		}
    		if (res == n || fen.query_prefix(res + 1) != a) {
    			res = -2;
    		}
    		if (a == 0) {
    			res = -1;
    		}
    		cout << res + 1 << "\n";
    	}
    }

    return 0;
}