Cod sursa(job #1660206)

Utilizator Iri00FII Irinel Manolache Iri00 Data 22 martie 2016 21:28:41
Problema Arbori indexati binar Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <stdio.h>
#include <fstream>
#include <cstring>
using namespace std;

#define dim 100001

inline int Minim(int a, int b) {
	if (a < b) return a;
	return b;
}

int N, M, T;
int Arb[dim];
int C, S;

void Update(int, int);
int Query(int);
int Search(int);

int main()
{
	memset(Arb, 0, sizeof(Arb));
	int K, X, Y;

	freopen("aib.in", "r", stdin);
	freopen("aib.out", "w", stdout);

	scanf("%d%d", &N, &M);
	for (int i = 1; i <= N; i++)
	{
		scanf("%d", &T);
		Update(i, T);
	}

	for (; M; M--)
	{
		scanf("%d", &K);

		if (K < 2)
		{
			scanf("%d%d", &X, &Y);
			if (!K) Update(X, Y);
			else      printf("%d\n", Query(Y) - Query(X - 1));
		}
		else
		{
			scanf("%d", &X);

			printf("%d\n", Search(X));
		}
	}
}

int Search(int Sum)
{
	int pos = N + 1, B;
	int limst = 0, limdr = N + 1;

	B = N;
	S = Query(B);

	if (S == Sum) pos = N;

	while (B)
	{
		B = (limst + limdr) >> 1;
		S = Query(B);

		if (S > Sum)
		{
			if (limdr > B) limdr = B;
			B -= 1;
		}
		else if (S == Sum) pos = Minim(pos, B), limdr = B, B -= 1;
		else
		{
			if (limst < B) limst = B;
			B += 1;
		}

		if (B <= limst) break;
		if (B >= limdr) break;
	}

	if (pos == N + 1) return -1;
	return pos;
}

void Update(int poz, int val)
{
	C = 0;
	while (poz <= N)
	{
		Arb[poz] += val;
		while (!(poz & (1 << C))) C++;
		poz += (1 << C);
		C += 1;
	}
}

int Query(int poz)
{
	C = 0, S = 0;
	while (poz > 0)
	{
		S += Arb[poz];
		while (!(poz & (1 << C))) C++;
		poz -= (1 << C);
		C += 1;
	}

	return S;
}