Cod sursa(job #382464)

Utilizator katakunaCazacu Alexandru katakuna Data 13 ianuarie 2010 18:48:12
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <cstdio>
#include <algorithm>
#include <list>
using namespace std;

#define Nmax 300010
#define MOD 666010

struct arbore {int min, max, dif_min, dif_max;} arb[Nmax * 4];

int nr, p, val, poz, tip, N, n1, n2;
int V[Nmax], viz[Nmax];
char s[16];
list <int> H[Nmax];

int find (int nr) {
	
	int nod = nr % MOD;
	for (list <int>::iterator it = H[nod].begin (); it != H[nod].end (); it++)
		if (*it == nr) return 1;
	
	return 0;
}

void citire () {
	FILE *f = fopen ("zeap.in", "r");
	
	fgets (s, 16, f);
	while (!feof (f)) {
		p = 0; nr = 0;
		while ((s[p] < '0' || s[p] > '9') && s[p] != '\n') p++;
		while (s[p] >= '0' && s[p] <= '9') 
			nr = nr * 10 + s[p] - '0', p++;
		
		if (nr && !find (nr)) {
			V[ ++V[0] ] = nr;
			H[nr % MOD].push_back (nr);
		}
		
		fgets (s, 16, f);
	}
	
	fclose (f);
}

void update (int nod, int st, int dr) {
	
	if (st == dr) {
		arb[nod].min = arb[nod].max = val;
		arb[nod].dif_max = arb[nod].dif_min = 0;
		return ;
	}
	
	if (poz <= ((st + dr) >> 1)) update ((nod << 1), st, ((st + dr) >> 1));
	else update ((nod << 1) + 1, ((st + dr) >> 1) + 1, dr);
	
	n1 = (nod << 1); n2 = (nod << 1) + 1;
	
	arb[nod].max = max (arb[n1].max, arb[n2].max);
	
	arb[nod].min = 0;
	if (arb[n1].min) arb[nod].min = arb[n1].min;
	if ( arb[n2].min && (!arb[nod].min || (arb[nod].min > arb[n2].min) )) arb[nod].min = arb[n2].min;
	
	arb[nod].dif_max = max (arb[n1].dif_max, arb[n2].dif_max);
	if (arb[n1].min && arb[n2].max) arb[nod].dif_max = max (arb[nod].dif_max, arb[n2].max - arb[n1].min);
	
	arb[nod].dif_min = 0;
	if (arb[n1].dif_min) arb[nod].dif_min = arb[n1].dif_min;
	if ( arb[n2].dif_min && (!arb[nod].dif_min || (arb[nod].dif_min > arb[n2].dif_min))) arb[nod].dif_min = arb[n2].dif_min;
	if ( arb[n2].min - arb[n1].max > 0&& (!arb[nod].dif_min || (arb[nod].dif_min > arb[n2].min - arb[n1].max)) ) arb[nod].dif_min = arb[n2].min - arb[n1].max;
}

int cauta (int X) {
	int p = 1, u = V[0], mij;
	
	while (p <= u) {
		mij = (p + u) >> 1;
		if (X <= V[mij])
			u = mij - 1;
		else
			p = mij + 1;
	}
	
	if (V[p] == X) return p;
	return 0;
}

int main () {
	
	citire ();
	sort (V + 1, V + V[0] + 1);
	
	FILE *f = fopen ("zeap.in", "r");
	FILE *g = fopen ("zeap.out", "w");
	
	fgets (s, 16, f);
	while (!feof (f)) {
		p = 0; nr = 0;
		while ((s[p] < '0' || s[p] > '9') && s[p] != '\n') p++;
		while (s[p] >= '0' && s[p] <= '9') 
			nr = nr * 10 + s[p] - '0', p++;
		
		if (s[1] == 'I') tip = 5;
		else {
			if (s[1] == 'A') tip = 4;
			else {
				if (s[0] == 'I') tip = 1;
				if (s[0] == 'S') tip = 2;
				if (s[0] == 'C') tip = 3;
			}
		}
		
		if (nr) p = cauta (nr);
		
		switch (tip) {
			case 1 : 
				if (!viz[p]) {
					N++; viz[p] = 1; val = nr; poz = p;
					update (1, 1, V[0]);
				}
				break;
			
			case 2 : 
				if (!viz[p]) fprintf (g, "-1\n");
				else {
					N--; viz[p] = 0; val = 0; poz = p;
					update (1, 1, V[0]);
				}
				break;
			
			case 3 : 
				if (!viz[p]) fprintf (g, "0\n");
				else fprintf (g, "1\n");
				break;
			
			case 4 : 
				if (N < 2) fprintf (g, "-1\n");
				else fprintf (g, "%d\n", arb[1].dif_max);
				break;
			
			case 5 : 
				if (N < 2) fprintf (g, "-1\n");
				else fprintf (g, "%d\n", arb[1].dif_min);
				break;
		}
		
		fgets (s, 16, f);
	}
	
	fclose (f);
	fclose (g);
	
	return 0;
}