Cod sursa(job #365433)

Utilizator stocarulCosmin-Mihai Tutunaru stocarul Data 18 noiembrie 2009 18:33:07
Problema Datorii Scor 20
Compilator c Status done
Runda Arhiva de probleme Marime 1.69 kb
#include<stdio.h>
#define infile "datorii.in"
#define outfile "datorii.out"
#define nmax 100001
int arb[nmax]; //valorile nodurilor arborelui de intervale
int poz; //pozitia din sirul initial la care se modifica o valoare
int val; //valoarea care se scade de la pozitia poz
int a,b; //intervalul in care trebuie calculata suma

void update(int rad, int st, int dr)
{
	if(st==dr) { arb[rad]+=val; return; } //adaugam valoarea la arbore
	int mij=(st+dr)/2; //jumatatea intervalului
	arb[rad]=0; //valoarea acestui nod o facem 0
	if(poz<=mij && rad*2<nmax) { update(rad*2,st,mij); arb[rad]+=arb[rad*2]; } else if(rad*2<nmax) arb[rad]+=arb[rad*2]; //nodul se afla in partea stanga
	if(mij<poz && rad*2+1<nmax) { update(rad*2+1,mij+1,dr); arb[rad]+=arb[rad*2+1]; } else if(rad*2+1<nmax) arb[rad]+=arb[rad*2+1]; //nodul se afla in partea dreapta
}

int query(int rad, int st, int dr)
{
	if(a<=st && dr<=b) return arb[rad]; //daca avem un interval complet
	int mij=(st+dr)/2; //jumatatea intervalului
	int val=0; //valoarea pe acest subarbore
	if(a<=mij && rad*2<nmax) val+=query(rad*2,st,mij); //partea stanga
	if(mij<b && rad*2+1<nmax) val+=query(rad*2+1,mij+1,dr); //partea dreapta
	return val; //returnam valoarea
}

int main()
{
	int n,m,x;
	freopen(infile,"r",stdin);
	freopen(outfile,"w",stdout);
	
	scanf("%d %d\n",&n,&m);
	
	//valorile initiale
	for(poz=1;poz<=n;poz++)
	{
		scanf("%d",&val);
		update(1,1,n);
	}
	
	//cele m operatii
	while(m--)
	{
		scanf("%d",&x); //tipul operatiei
		if(x)
		{ //daca avem query
			scanf("%d %d\n",&a,&b);
			printf("%d\n",query(1,1,n));
		}
		else
		{ //daca avem updatte
			scanf("%d %d\n",&poz,&val);
			val*=(-1);
			update(1,1,n);
		}
	}
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}