Cod sursa(job #2803676)

Utilizator schizofrenieShallan Davar schizofrenie Data 20 noiembrie 2021 12:34:04
Problema Datorii Scor 60
Compilator c-64 Status done
Runda Arhiva de probleme Marime 2.72 kb
#include <assert.h>
#include <stdio.h>

#define MAXN 15000

#define LEFT(nod) ((nod * 2) + 1)
#define RIGHT(nod) ((nod * 2) + 2)

int
MAX (int a, int b) {
	if (a < b)
		return b;
	return a;
}


int n;
int v[MAXN];
int aint[MAXN * 2 + 1];

int  query   (int left, int right);
int  _query  (int left, int right, int node, int aintleft, int aintright);
void update  (int poz, int value);
void _update (int poz, int value, int node, int aintLeft, int aintRight);
void build   ();
void _build  (int node, int aintLeft, int aintRight);

int
query (int left, int right) {
	return _query(left, right, 0, 0, n);
}

int
_query (int left, int right, int node, int aintLeft, int aintRight) {
	assert(aintLeft < aintRight);

	if (left <= aintLeft && aintRight <= right)
		return aint[node];

	int mid = (aintLeft + aintRight) / 2;
	int sum = 0;

	if (left < mid)
		sum += _query(left, right, LEFT(node), aintLeft, mid);

	if (mid < right)
		sum += _query(left, right, RIGHT(node), mid, aintRight);

	return sum;
}

void
update (int poz, int val) {
	_update(poz, val, 0, 0, n);
}

void
_update (int poz, int val, int node, int aintLeft, int aintRight) {
	assert(aintLeft < aintRight);

	if (poz == aintLeft && poz == aintRight - 1) {
		aint[node] -= val;
		return;
	}

	int mid = (aintLeft + aintRight) / 2;

	if (poz < mid)
		_update(poz, val, LEFT(node), aintLeft, mid);
	else
		_update(poz, val, RIGHT(node), mid, aintRight);

	aint[node] = aint[LEFT(node)] + aint[RIGHT(node)];
}

void
build () {
	_build(0, 0, n);
}

void
_build (int node, int aintLeft, int aintRight) {
	assert(aintLeft < aintRight);

	if (aintLeft == aintRight - 1) {
		aint[node] = v[aintLeft];
		return;
	}

	int mid = (aintLeft + aintRight) / 2;

	_build(LEFT(node), aintLeft, mid);
	_build(RIGHT(node), mid, aintRight);

	aint[node] = aint[LEFT(node)] + aint[RIGHT(node)];
}

void
_parcurge (int node, int aintLeft, int aintRight) {
	assert(aintLeft < aintRight);

	int mid = (aintLeft + aintRight) / 2;

	if (aintLeft != mid) {
		_parcurge(LEFT(node), aintLeft, mid);
		_parcurge(RIGHT(node), mid, aintRight);
	}

	fprintf(stderr, "Pentru intervalul [%d,%d) maximul este %d\n", aintLeft + 1, aintRight + 1, aint[node]);
}


int main () {
	int m;
	int i;

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

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

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

	build();
	// _parcurge(0, 0, n);
	// fputs("------\n", stderr);

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

		assert(scanf(" %d %d %d", &tip, &a, &b) == 3);

		switch (tip) {
		case 1:
			printf("%d\n", query(a - 1, b));
			break;
		case 0:
			update(a - 1, b);

			// _parcurge(0, 0, n);
			// fputs("------\n", stderr);
			break;
		default:
			assert(0);
		}
	}
}