Cod sursa(job #728069)

Utilizator fhandreiAndrei Hareza fhandrei Data 28 martie 2012 14:31:27
Problema Arbori indexati binar Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.96 kb
//Include
#include <cstdio>
using namespace std;

//Definitii
#define leftSon node<<1
#define rightSon (node<<1)+1

//Constante
const int MAX_SIZE = (int)1e5+1;

//Functii
void update(int, int, int);
void query(int, int, int);

//Variabile

int n, q;
int question;
int poz, val, sum;
int sumaCautata;
int intervalLeft, intervalRight;
int tree[MAX_SIZE<<2];

bool found;

//Main
int main()
{
	freopen("aib.in", "rt", stdin);
	freopen("aib.out", "wt", stdout);
	scanf("%d%d", &n, &q);
	
	for(poz=1 ; poz<=n ; ++poz)
	{
		scanf("%d", &val);
		update(1, 1, n);
	}
	
	for(int i=1 ; i<=q ; ++i)
	{
		scanf("%d", &question);
		switch(question)
		{
			case 0:
			{
				scanf("%d%d", &poz, &val);
				update(1, 1, n);
				break;
			}
			case 1:
			{
				scanf("%d%d", &intervalLeft, &intervalRight);
				sum = 0;
				query(1, 1, n);
				printf("%d\n", sum);
				break;
			}
			default:
			{
				intervalLeft = 1;
				scanf("%d", &sumaCautata);
				
				int left = 1, right = n, sumMid;
				found = false;
				while(left <= right)
				{
					int mid = (left + right) >> 1;
					intervalRight = mid;
					sum = 0;
					query(1, 1, n);
					sumMid = sum;
					if(sumMid == sumaCautata)
					{
						printf("%d\n", mid);
						found = true;
						break;
					}
					
					if(sumaCautata < sumMid)
						right = mid - 1;
					else
						left = mid + 1;
				}
				if(!found)
					printf("-1\n");
			}
		}
	}
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

void update(int node, int left, int right)
{
	if(left == right)
	{
		tree[node] += val;
		return ;
	}
	
	int mid = (left + right) >> 1;
	if(poz <= mid)
		update(leftSon, left, mid);
	else
		update(rightSon, mid+1, right);
	
	tree[node] = tree[leftSon] + tree[rightSon];
}

void query(int node, int left, int right)
{
	if(intervalLeft <= left && right <= intervalRight)
	{
		sum += tree[node];
		return;
	}
	
	int mid = (left + right) >> 1;
	
	if(intervalLeft <= mid)
		query(leftSon, left, mid);
	if(mid < intervalRight)
		query(rightSon, mid+1, right);
}