Cod sursa(job #2006)

Utilizator MariusMarius Stroe Marius Data 15 decembrie 2006 17:41:13
Problema Zeap Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.17 kb
#include <cstdio>
using namespace std;

const char iname[] = "zeap.in";
const char oname[] = "zeap.out";

#define MAX_N   300005
#define MAX_BUF 5000000
#define MAX_DIM 1048576

#define isnum(z)    ('0' <= (z) && (z) <= '9')
#define ischar(z)   ('A' <= (z) && (z) <= 'Z')
#define shift(z, w) ((z) ^= (w) ^= (z) ^= (w))

#define left  (2 * n)
#define right (2 * n + 1)
#define mid   ((st + dr) / 2)

int N, V[MAX_N], E[MAX_N];

int H[MAX_N];

int T[MAX_DIM], Max[MAX_DIM], Min[MAX_DIM], MinDif[MAX_DIM], MaxDif[MAX_DIM];

char buffer[MAX_BUF];


void insert(int H[], int value)
{
	int k;

	for (k = (++H[0]); k > 1 && H[k >> 1] > value; k >>= 1)
		H[k] = H[k >> 1];
	H[k] = value;
}

void down(int H[], int z)
{
	int l, r, k;
	int done;

	for (done = 0; !done; ) {
		l = 2 * z;
		r = 2 * z + 1;
		k = z;
		if (l <= H[0] && H[l] < H[k])
			k = l;
		if (r <= H[0] && H[r] < H[k])
			k = r;
		if (k != z)
			shift(H[k], H[z]), z = k;
		else
			done = 1;
	}
}

int getmin(int H[])
{
	int M = H[1];

	H[1] = H[H[0]--];
	if (H[0] > 1)
		down(H, 1);
	return M;
}

int search(const int V[], const int value)
{
	int k;
	int step;

	for (step = 1; step <= V[0]; step <<= 1) ;
	for (k = 0; step; step >>= 1)
		if (k + step <= V[0] && V[k + step] <= value)
			k += step;
	
	return k;
}

void build(int n, int st, int dr)
{
	if (st == dr) {
		Min[n] = Max[n] = V[st];
		return ;
	}
	build(left, st, mid);
	build(right, mid + 1, dr);
}

void update(int n, int st, int dr, int p)
{
	if (st == dr) {
		if (E[p] == 1)
			T[n] += 1;
		else 
			T[n] -= 1;
		return ;
	}
	if (p <= mid)
		update(left, st, mid, p);
	else
		update(right, mid + 1, dr, p);
	
	T[n] = T[left] + T[right];
	if (T[n] > 0) {
		if (T[left] > 0) {
			Min[n] = Min[left],	Max[n] = Max[left];
			if (T[right] > 0) {
				if (Min[n] > Min[right])
					Min[n] = Min[right];
				if (Max[n] < Max[right])
					Max[n] = Max[right];
			}
		} else
			Min[n] = Min[right], Max[n] = Max[right];
	}
	if (T[left] > 1 || T[right] > 1) {
		if (T[left] > 1) {
			MinDif[n] = MinDif[left], MaxDif[n] = MaxDif[left];
			if (T[right] > 1) {
				if (MinDif[n] > MinDif[right])
					MinDif[n] = MinDif[right];
				if (MaxDif[n] < MaxDif[right])
					MaxDif[n] = MaxDif[right];
			}
		} else
			MinDif[n] = MinDif[right], MaxDif[n] = MaxDif[right];
		
		if (T[left] > 0 && T[right] > 0) {
			if (MinDif[n] > Min[right] - Max[left])
				MinDif[n] = Min[right] - Max[left];
			if (MaxDif[n] < Max[right] - Min[left])
				MaxDif[n] = Max[right] - Min[left];
		}
	} else if (T[n] == 2)
		MinDif[n] = Min[right] - Max[left], MaxDif[n] = Max[right] - Min[left];
}

inline char* getnum(char *p, char *lim, int & V)
{
	for (; p < lim && !isnum(*p) && !ischar(*p); ++p)
		;
	for (V = 0; p < lim && isnum(*p); ++p)
		V = V * 10 + (*p) - '0';

	return p;
}

inline char* getstr(char *p, char *lim, char *str)
{
	for (; p < lim && !ischar(*p) && !isnum(*p); ++p)
		;
	for (; p < lim &&  ischar(*p); ++p)
		*str++ = *p;

	return p;
}

int main(void)
{
	freopen(iname, "r", stdin);
	freopen(oname, "w", stdout);
	int i;
	int v;
	int len;

	char *p, *lim, str[4];

	len = int(fread(buffer, sizeof(char), MAX_BUF, stdin));
	
	for (p = buffer, lim = buffer + len; p < lim; ) {
		p = getnum(p, lim, v);
		if (v > 0)
			insert(H, v);
	}
	for (; H[0] > 0; ) {
		if (V[0] > 0)
			while (H[1] == V[V[0]])
				V[V[0]] = getmin(H);
		V[++V[0]] = getmin(H);
	}
	build(1, 1, V[0]);
	for (p = buffer, lim = buffer + len; p < lim; ) {
		p = getstr(p, lim, str);
		if (str[0] == 'M') {
			if (str[1] == 'I') {
				if (T[1] > 1)
					printf("%d\n", MinDif[1]);
				else
					printf("-1\n");
			} else if (str[1] == 'A') {
				if (T[1] > 1)
					printf("%d\n", MaxDif[1]);
				else
					printf("-1\n");
			}
		} else if (p < lim) {
			p = getnum(p, lim, v);
			i = search(V, v);
			if (str[0] == 'I') {
				if (E[i] == 0)
					E[i] = 1, update(1, 1, V[0], i);
			}
			else if (str[0] == 'S') {
				if (E[i] == 1)
					E[i] = 0, update(1, 1, V[0], i);
				else
					printf("-1\n");
			} else if (str[0] == 'C')
				printf("%d\n", E[i]);
		}
	}

	return 0;
}