Cod sursa(job #253410)

Utilizator willliIonel Bratianu willli Data 5 februarie 2009 19:19:36
Problema Arbori indexati binar Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 2.35 kb
#include <stdio.h>
#include <stdlib.h>
#define MAX 100001
#define in "aib.in"
#define out "aib.out"

long tree[5*MAX], N, numb[5*MAX];

void insert(long node, long left, long right, long poz, long value)
{
	long m, t;
	if (left >= right)
	{
		if (tree[node] == 0)
			numb[node / 2]++;
		tree[node] += value;	
		numb[node ] = 0;	
	}
	else 
	{
		m = (left + right) / 2;
		t = numb[node];
		if (poz <= m)
			insert(2*node, left, m, poz, value);
		else		
			insert(2*node+1, m+1, right, poz, value);
		tree[node] = tree[2*node] + tree[2*node+1];
		if (t != numb[node])
			numb[node / 2]++;
	}
}


long find(long node, long left, long right, long a, long b)
{
	long x = 0, y = 0, m;
	if (a <= left && b >= right)
		return tree[node];
	else
	{
		m = (left + right) / 2;
		if (a <= m)
			x = find(2*node, left, m, a, b);
		if (b > m)
			y = find(2 * node + 1, m + 1, right, a, b);
		return x + y;	
	}
}


long sum(long node, long left_nodes,long total)
{
	long x = 0;
	if (tree[node] == total)
	{
		if (numb[node] == 0)
			//leaf
			return left_nodes + 1;
		else
			return left_nodes + numb[node];
	}
	else if (numb[node] == 0)
	{
		return -1;
	}
	else
	{
		x = tree[node] - total;
		if  (tree[node] < total)
		{
			return -1;
		}
		else if (total <= tree[2 * node] )
			return sum(2*node, left_nodes, total);
		else if (x > tree[2 * node + 1])
			return -1;
		else 
			return sum(2*node+1, numb[2*node], x);		
	}
}

int main()
{
	long a[MAX], n, i, z, m, x, y;
	FILE *fin, *fout;
	
	if ((fin = fopen(in, "r")) == NULL)
	{
		printf("Eroare \n");
		exit(-1);
	}
	//read dimension of vectors
	fscanf(fin, "%ld%ld", &n, &m);

	//read the vectors
	for (i = 1; i<=n ; i++)
	{
		fscanf(fin, "%ld", &a[i]);
		insert(1, 1, n, i, a[i]);
	}
	fout = fopen(out, "w");
	/*
	for (i = 0; i <= 2 * n + 1; i++)
		printf("%ld ", tree[i]);		
	printf("\n");
	*/
	for (i = 0; i < m; i++)
	{
		fscanf(fin, "%ld%ld", &x, &y);
		if (x == 0)
		{
			fscanf(fin, "%ld", &z);
			insert(1, 1, n, y, z);
			//printf("Interval [%ld %ld] are maximul %ld\n", y, z, j);
		}
		else if (x == 1)
		{
			fscanf(fin, "%ld", &z);
			z = find(1, 1, n, y, z);
			fprintf(fout, "%ld\n", z);
			/*for (j = 0; j <= 2 * n + 1; j++) find(long node, long left, long right, long a, long b)
				printf("%ld ", tree[j]);
			printf("\n");*/
		} else if (x == 2)
		{
			z = sum(1, 0, y);
			fprintf(fout, "%ld\n", z);
		}
	}
	fclose(fin);
	fclose(fout);
	return 0;
}