Cod sursa(job #2803742)

Utilizator schizofrenieShallan Davar schizofrenie Data 20 noiembrie 2021 13:28:33
Problema Arbori indexati binar Scor 100
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.21 kb
#include <assert.h>
#include <stdio.h>

#define MAXN 100000

#define LEASTSIG(x) (1 << (__builtin_ctz(x)))

int n;
int v[MAXN + 1];
int aib[MAXN + 1];

void
update (int poz, int val) {
	int i;
	for (i = poz; i <= n; i += LEASTSIG(i))
		aib[i] += val;
}

int
compute (int node) {
	int ret = 0;
	int i;

	for (i = node; i > 0; i -= LEASTSIG(i))
		ret += aib[i];

	return ret;
}


int
binSearch (int sum) {
	int bg = 0;
	int i;
	for (i = 1 << 24; i; i >>= 1)
		if (bg + i <= n && compute(bg + i) < sum)
			bg += i;

	if ((++ bg) <= n && compute(bg) == sum)
		return bg;
	return -1;
}

int main () {
	int m;
	int i;

	assert(freopen("aib.in", "r", stdin));
	assert(freopen("aib.out", "w", stdout));

	assert(scanf("%d %d", &n, &m) == 2);

	for (i = 0; i != n; ++ i) {
		assert(scanf("%d", &v[i]) == 1);
		update(i + 1, v[i]);
	}

	for (i = 0; i != m; ++ i) {
		int tip, a, b;

		assert(scanf(" %d", &tip) == 1);

		switch (tip) {
		case 0:
			assert(scanf(" %d %d", &a, &b) == 2);
			update(a, b);
			break;
		case 1:
			assert(scanf(" %d %d", &a, &b) == 2);
			printf("%d\n", compute(b) - compute(a - 1));
			break;
		case 2:
			assert(scanf(" %d", &a) == 1);
			printf("%d\n", binSearch(a));
			break;
		default:
			assert(0);
		}
	}
}