Cod sursa(job #2216811)

Utilizator TincaMateiTinca Matei TincaMatei Data 28 iunie 2018 00:44:50
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <bits/stdc++.h>

using namespace std;

template <typename T, int n, T neutral, typename sum = std::plus<T> >
class Aib {
private:
	T* aib;
	sum adder;
	inline int lsb(int x) {
		return x & (-x);
	}
public:
	Aib() {
		aib = new T[1+n];
		for(int i = 1; i <= n; ++i)
			aib[i] = neutral;
	}
	void update(int poz, T val) {
		while(poz <= n) {
			this->aib[poz] = adder(this->aib[poz], val);
			poz += this->lsb(poz);
		}
	}
	T query(int poz) {
		T rez = this->aib[poz];
		poz -= this->lsb(poz);
		while(poz > 0) {
			rez = adder(this->aib[poz], rez);
			poz -= this->lsb(poz);
		}
		return rez;
	}
};

const int MAX_N = 100000;
Aib<int, MAX_N, 0> aib;

int main() {
#ifdef HOME
	FILE *fin = fopen("input.in", "r");
	FILE *fout = fopen("output.out", "w");
#else
	FILE *fin = fopen("aib.in", "r");
	FILE *fout = fopen("aib.out", "w");
#endif
	
	int n, m, x, y, t;
	fscanf(fin, "%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) {
		fscanf(fin, "%d", &x);
		aib.update(i, x);
	}

	for(int i = 0; i < m; ++i) {
		fscanf(fin, "%d", &t);
		if(t == 0) {
			fscanf(fin, "%d%d", &x, &y);
			aib.update(x, y);
		} else if(t == 1) {
			fscanf(fin, "%d%d", &x, &y);
			fprintf(fout, "%d\n", aib.query(y) - aib.query(x - 1));
		} else {
			if(t == 2) {
				fscanf(fin, "%d", &x);
				int st, dr;
				st = 0, dr = n + 1;
				
				while(dr - st > 1) {
					int mid = (st + dr) / 2;
					if(aib.query(mid) < x)
						st = mid;
					else
						dr = mid;
				}

				if(aib.query(dr) != x)
					fprintf(fout, "-1\n");
				else
					fprintf(fout, "%d\n", dr);
			}
		}
	}

#ifdef HOME
	fclose(fin);
	fclose(fout);
#endif
	return 0;
}