Cod sursa(job #113808)

Utilizator plastikDan George Filimon plastik Data 11 decembrie 2007 18:05:26
Problema Datorii Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
#include <cstdio>

const int MAX_V = 18000;
const int MAX_N = 15005;

struct node {
	int l, r;
	int sum;
} A[MAX_V];

int V[MAX_V], m, n;

int makeIntervalTree(int root, int l, int r) {
	A[root].l = l;
	A[root].r = r;
	if (l == r) {
		A[root].sum = V[l - 1];
		return A[root].sum;
	}
	
	int m = (l + r) / 2;
	return A[root].sum = makeIntervalTree(root * 2, l, m) + makeIntervalTree(root * 2 + 1, m + 1, r);
}
inline int min(int a, int b) {
	if (a < b)
		return a;
	return b;
}
inline int max(int a, int b) {
	if (a > b)
		return a;
	return b;
}
int queryIntervalTree(int root, int l, int r) {
	if (A[root].l == l && A[root].r == r) {
		//printf("%d %d\n", A[root].l, A[root].r);
		return A[root].sum;
	}
	int left = 2 * root, right = 2 * root + 1, s1 = 0, s2 = 0;
	if (A[left].l <= l && l <= A[left].r)
		s1 = queryIntervalTree(left, l, min(A[left].r, r));
	if (A[right].l <= r && r <= A[right].r)
		s2 = queryIntervalTree(right, max(l, A[right].l), r);
	return s1 + s2;
}

void updateIntervalTree(int root, int dif) {
	if (root < 1)
		return;
	A[root].sum -= dif;
	updateIntervalTree(root / 2, dif);
}

void printIntervalTree(int root) {
	printf("%d %d %d\n", A[root].l, A[root].r, A[root].sum);
	if (A[root].l == A[root].r) 
		return;
	printIntervalTree(2 * root);
	printIntervalTree(2 * root + 1);
}

int main() {
	freopen("datorii.in", "r", stdin);
	freopen("datorii.out", "w", stdout);
	
	scanf("%d %d", &n, &m);
	int i, p2 = 1;
	while (p2 < n)
		p2 *= 2;
	//printf("%d\n", p2);
	for (i = 0; i < n; ++ i)
		scanf("%d", &V[i]);
	for (; i < p2; ++ i)
		V[i] = 0;
	
	makeIntervalTree(1, 1, p2);
	/*-updateIntervalTree(p2 + 1, 2);
	//printIntervalTree(1);
	int l, r;
	l = 1;
	r = 3;
	printf("%d %d %d\n", l, r, queryIntervalTree(1, l, r));*/
	
	int t, v1, v2;
	for (i = 0; i < m; ++ i) {
		scanf("%d %d %d", &t, &v1, &v2);
		if (t == 1)
			printf("%d\n", queryIntervalTree(1, v1, v2));
		else
			updateIntervalTree(p2 + v1 - 1, v2);
	}
	
	return 0;
}