Pagini recente » Cod sursa (job #2405969) | Cod sursa (job #2641875) | Cod sursa (job #2860578) | Cod sursa (job #760355) | Cod sursa (job #591964)
Cod sursa(job #591964)
#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;
}