Cod sursa(job #3203425)

Utilizator amcbnCiobanu Andrei Mihai amcbn Data 13 februarie 2024 17:37:36
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
const char nl = '\n';
const char sp = ' ';
const int inf = 0x3f3f3f3f;
const int mod = 666013;
const char out[2][4]{ "NO", "YES" };
#define all(a) a.begin(), a.end()
using ll = long long;
//ifstream fin("bfs.in");
ofstream fout("aib.out");

const int nmax = 1e5;
int n, q;
ll t[nmax + 5]{ 0 };

class InParser {
private:
	FILE* fin;
	char* buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int& n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		}
		else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long& n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		}
		else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
} fin("aib.in");

inline void add(int i, ll x) {
	for (; i <= n; i += i & -i) {
		t[i] += x;
	}
}

inline ll get(int i) {
	ll sum = 0;
	for (; i > 0; i -= i & -i) {
		sum += t[i];
	}
	return sum;
}

inline ll get(int i, int j) {
	return get(j) - get(i - 1);
}

inline int search(ll a) {
	// primul care are suma == a
	// (ultimul care are suma < a) + 1
	int p = 1; // cea mai mare putere de 2 <= n
	while ((2 << p) <= n) {
		++p;
	}
	int k = 0;
	ll sum = 0;
	for (; p >= 0; --p) {
		if (k + (1 << p) <= n && sum + t[k + (1 << p)] < a) {
			sum += t[k += (1 << p)];
		}
	}
	if (k == n) {
		return -1;
	}
	return get(++k) == a ? k : -1;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	fin >> n >> q;
	for (int i = 1; i <= n; ++i) {
		int x;
		fin >> x;
		t[i] += x;
		if (i + (i & -i) <= n) {
			t[i + (i & -i)] += t[i];
		}
	}
	while (q--) {
		int x, a, b;
		fin >> x >> a;
		if (x == 0) {
			fin >> b;
			add(a, b);
		}
		else if (x == 1) {
			fin >> b;
			fout << get(a, b) << nl;
		}
		else {
			fout << search(a) << nl;
		}
	}
}