Cod sursa(job #727477)

Utilizator fhandreiAndrei Hareza fhandrei Data 27 martie 2012 23:47:14
Problema Arbori indexati binar Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
//Include
#include <fstream>
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
ifstream in("aib.in");
ofstream out("aib.out");

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

bool found;

//Main
int main()
{
	in >> n >> q;
	
	for(poz=1 ; poz<=n ; ++poz)
	{
		in >> val;
		update(1, 1, n);
	}
	
	for(int i=1 ; i<=q ; ++i)
	{
		in >> question;
		switch(question)
		{
			case 0:
			{
				in >> poz >> val;
				update(1, 1, n);
				break;
			}
			case 1:
			{
				in >> intervalLeft >> intervalRight;
				sum = 0;
				query(1, 1, n);
				out << sum << '\n';
				break;
			}
			default:
			{
				intervalLeft = 1;
				in >> 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)
					{
						out << mid << '\n';
						found = true;
						break;
					}
					
					if(sumaCautata < sumMid)
						right = mid - 1;
					else
						left = mid + 1;
				}
				if(!found)
					out << "-1\n";
			}
		}
	}
	
	in.close();
	out.close();
	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);
}