Cod sursa(job #2282628)

Utilizator marcudanfDaniel Marcu marcudanf Data 14 noiembrie 2018 10:41:49
Problema Arbori indexati binar Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.26 kb
#include <cstdio>

const int NMAX = 1e5 + 5;

using namespace std;

FILE *INPUT = fopen("aib.in", "r");
FILE *OUTPUT = fopen("aib.out", "w");

int a[NMAX];
int n, m;

void create_aib(){
	for(int ix = 1; ix <= n; ix++){
		int ix2 = ix + (ix & (-ix));
		if(ix <= n)
			a[ix2] += a[ix];
	}
}

void update(int ix, int val){
	while(ix <= n){
		a[ix] += val;
		ix += ix & (-ix);
	}
}

int prefix(int ix){
	int res = 0;
	while(ix){
		res += a[ix];
		ix -= ix & (-ix);
	}
	return res;
}

int range(int ix1, int ix2){
	return prefix(ix2) - prefix(ix1 - 1);
}

int search(int val){
	int logn;
	for(logn = 1; logn <= n; logn <<= 1);
	for(int step = logn, i = 0; step; step >>= 1){
		if( i + step <= n and a[i + step] <= val){
			val -= a[i + step];
			i += step;
		}
		if(val == 0)
			return i;
	}
	return -1;
}

int main(){
	fscanf(INPUT, "%d %d", &n, &m);
	for(int i = 1; i <= n; i++)
		fscanf(INPUT, "%d", &a[i]);
	create_aib();
	while(m--){
		int task;
		fscanf(INPUT, "%d", &task);
		if(task == 0){
			int n1, n2;
			fscanf(INPUT, "%d %d", &n1, &n2);
			update(n1, n2);
		}else if(task == 1){
			int n1, n2;
			fscanf(INPUT, "%d %d", &n1, &n2);
			fprintf(OUTPUT, "%d\n", range(n1, n2));
		}else{
			int n1;
			fscanf(INPUT, "%d", &n1);
			fprintf(OUTPUT, "%d\n", search(n1));
		}
	}
	return 0;
}