Cod sursa(job #591964)

Utilizator rudarelLup Ionut rudarel Data 26 mai 2011 09:08:01
Problema Datorii Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <stdio.h>
#define INFILE "datorii.in"
#define OUTFILE "datorii.out"
#define MAX 15001

long int sum[MAX];
int n;

void ReadDataAndSolve();
void Modify(int pos, int value);
long int Sum(int l, int r);

int main()
{
	ReadDataAndSolve();

	return 0;
}

void ReadDataAndSolve()
{
	freopen(INFILE, "r", stdin);
	freopen(OUTFILE, "w", stdout);

	int i = 0, val = 0, type = 0, p1 = 0, p2 = 0;
	long int m = 0;

	scanf("%d %ld", &n, &m);

	for ( i = 1; i <= n; i++ )
	{
		scanf("%d", &val);
		Modify(i, val);
	}

	for ( i = 1; i <= m; i++ )
	{
		scanf("%d", &type);
		if ( !type )
		{
			scanf("%d %d", &p1, &val);
			Modify(p1, -val); // elem de pe poz p1 scade cu val
		}
		else
		{
			scanf("%d %d", &p1, &p2);
			printf("%ld\n", Sum(p1, p2));
		}
	}

	fclose(stdin);
	fclose(stdout);
}

void Modify(int pos, int value)
{
	int nr0 = 0; // modifica elementul de pe poz pos si toate care
        // depind de el cu value

        // nr0 - reprezinta numarul de 0-uri

	while ( pos <= n )
	{
		sum[pos] += value;
		while ( !(pos & (1 << nr0)) )
			nr0++; // numar cate 0-uri terminale are poz in reprezentare
		pos += 1 << nr0; // poz urmatoare se obtine adunanda 2^nr0
		nr0++; // prin adunare voi avea cel putin inca un 0 terminal
	}
}

long int Sum(int l, int r)
{
	long int s1 = 0, s2 = 0, nr0 = 0;

        // suma de la 1..r si de la 1..(l-1)
        // si le scad

	while ( r > 0 ) // pana cand mai gasesc elem de care depinde suma
	{
		s1 += sum[r];
		while ( !(r & (1 << nr0)) )
			nr0++; // cresc numarul de 0-uri binare din reprezenarea binara
                // a lui r
		r -= 1 << nr0; // poz urmatoare de care depinde suma se obtine scazand 2^nr0
		nr0++; // prin scadere se adauga cel putin un 0 terminal
	}

	nr0 = 0;

	l--; // pentru l - 1

	while ( l > 0 ) // la fel
	{
		s2 += sum[l];
		while ( !(l & (1 << nr0)) )
			nr0++;
		l -= 1 << nr0;
		nr0++;
	}

	return s1 - s2;
}