Cod sursa(job #50951)

Utilizator scapryConstantin Berzan scapry Data 9 aprilie 2007 14:22:28
Problema Datorii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.3 kb
#include <assert.h>
#include <stdio.h>

enum { maxn = 15001 };

int n;
int t[maxn];

int zeros(int num)
{
	assert(num > 0);

	int ret = num ^ (num - 1);
	ret++;
	ret >>= 1;

	//expensive
	/*int check;
	for(check = 0; (num & (1 << check)) == 0; check++);

	assert(1 << check == ret);*/

	return ret;
}

void modify(int pos, int add)
{
	assert(pos > 0 && pos <= n);
	
	for(; pos <= n; pos += zeros(pos)) {
		t[pos] += add;
		assert(t[pos] >= 0);
	}
}

int query_one(int pos)
{
	int ret = 0;

	assert(pos >= 1 && pos <= n);

	for(; pos != 0; pos -= zeros(pos))
		ret += t[pos];

	return ret;
}

inline int query(int left, int right)
{
	assert(left > 0);
	assert(left <= right);
	assert(right <= n);

	int left_val;
	if(left == 1) left_val = 0;
	else left_val = query_one(left - 1);
	return query_one(right) - left_val;
}

int main()
{
	int i, ops, type, a, b, ans;
	FILE *f = fopen("datorii.in", "r"),
	     *fo = fopen("datorii.out", "w");
	if(!f || !fo) return 1;

	fscanf(f, "%d%d", &n, &ops);

	for(i = 0; i < n; i++) {
		fscanf(f, "%d", &a);
		modify(i + 1, a);
	}

	for(i = 0; i < ops; i++) {
		fscanf(f, "%d%d%d", &type, &a, &b);
		if(type == 0) { //modify
			modify(a, -b); //subtracting!
		}
		else if(type == 1) { //query
			ans = query(a, b);

			fprintf(fo, "%d\n", ans);
		}
	}

	fclose(f);
	fclose(fo);
	return 0;
}