Cod sursa(job #2677363)

Utilizator Alin_StanciuStanciu Alin Alin_Stanciu Data 26 noiembrie 2020 12:38:29
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
#define MAX_N 100000

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("aib.in");
ofstream fout("aib.out");

int n, m, A[MAX_N + 1];
vector<int> G[21]; // G[i][j] - suma secventei j de lungime 2^i.

void CalcArb()
{
	G[0] = vector<int>(n + 1);
	
	for (int i = 1; i <= n; ++i)
	{
		G[0][i] = A[i];
	}
	
	for (int e = 0, p = 1; p < n; ++e, p *= 2)
	{
		G[e + 1] = vector<int>(G[e].size() / 2 + 1);
		
		for (int i = 1; i < (int)G[e + 1].size(); ++i)
		{
			G[e + 1][i] = G[e][i * 2] + G[e][i * 2 - 1];
		}
	}
}

void Adauga(int a, int b)
{
	for (int e = 0; (int)G[e].size() > 0; ++e)
	{
		G[e][a] += b;
		a = (a + 1) / 2;
	}
}

int Suma(int e, int a, int b) // Suma de la nodul (e, a) la (e, b).
{
	int s = 0;
	
	while (a != b)
	{
		if (a % 2 == 0)
		{
			s += G[e][a];
			++a;
			
			continue;
		}
		
		if (b % 2 == 1)
		{
			s += G[e][b];
			--b;
			
			continue;
		}
		
		++e;
		a = a / 2 + 1, b /= 2;
	}
	
	return s + G[e][a];
}

int DetK(int a)
{
	int st = 1, dr = n;
	
	while (st <= dr)
	{
		int mij = (st + dr) / 2;
		
		int s = Suma(0, 1, mij);
		
		if (s == a)
		{
			return mij;
		}
		
		if (s > a)
		{
			dr = mij - 1;
		}
		else
		{
			st = mij + 1;
		}
	}
	
	return -1;
}

void AfisareArb()
{
	for (int e = 0; G[e].size() > 0; ++e)
	{
		cout << "e = " << e << ": ";
		
		for (int i = 1; i < (int)G[e].size(); ++i)
		{
			cout << G[e][i] << " ";
		}
		
		cout << '\n';
	}
	
	cout << '\n';
}

int main()
{
	fin >> n >> m;
	
	for (int i = 1; i <= n; ++i)
	{
		fin >> A[i];
	}
	
	CalcArb();
	
	for (int i = 1; i <= m; ++i)
	{
		int c;
		fin >> c;
		
		switch (c)
		{
			case 0:
			{
				int a, b;
				fin >> a >> b;
				
				Adauga(a, b);
				
				break;
			}
			
			case 1:
			{
				int a, b;
				fin >> a >> b;
				
				fout << Suma(0, a, b) << '\n';
				
				break;
			}
			
			case 2:
			{
				int a;
				fin >> a;
				
				fout << DetK(a) << '\n';
				
				break;
			}
		}
	}
 
    return 0;
}