Cod sursa(job #2008)

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

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

#define MAX_N   300001
#define MAX_BUF 5000000
#define INF     (int(1e9))

int  H[MAX_N];

int  A[MAX_N], X[MAX_N];

int  T[MAX_N * 3], Min[MAX_N * 3], Max[MAX_N * 3], MaxDif[MAX_N * 3], MinDif[MAX_N * 3];

int  LOG;

char buf[MAX_BUF];


inline bool isnum(const char z) {
	return ('0' <= z && z <= '9');
}

inline bool ischar(const char z) {
	return ('A' <= z && z <= 'Z');
}

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

	for (;;) {
		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)
			return;
		H[k] ^= H[z] ^= H[k] ^= H[z], z = k;
	}
}

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

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

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

	H[1] = H[(H[0]--)];
	if (H[0] > 1)
		rebuild(H, 1);
	return min;
}

int search(const int A[], const int V)
{
	int k;
	int step = LOG;

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

#define left  (n << 1)
#define right (left + 1)
#define mid   ((st + dr) >> 1)


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

void update(int n, int st, int dr, int p)
{
	if (st == dr) {
		if (X[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];
}

int main(void)
{
	freopen(iname, "r", stdin);
	freopen(oname, "w", stdout);
	int  V;
	int  len;
	char * p, * lim, ch;

	int  k;

	len = int(fread(buf, sizeof(char), MAX_BUF, stdin));

	for (p = buf, lim = buf + len; p < lim; ) {
		for (; p < lim && !isnum(*p); ++p) 
			;
		if (p < lim) {
			for (V = 0; p < lim && isnum(*p); ++p)
				V = V * 10 + (*p) - '0';
			insert(H, V);
		}
	}
	for (; H[0] > 0;) {
		A[(++A[0])] = getmin(H);
		if (A[0] > 1 && A[A[0]] == A[A[0] - 1])
			A[0] -= 1;
	}
	buildTree(1, 1, A[0]);
	
	for (LOG = 1; LOG <= A[0]; LOG <<= 1) 
		;

	for (p = buf, lim = buf + len; p < lim; ) {
		for (; p < lim && !isnum(*p) && !ischar(*p); ++p)
			;
		if (p == lim)
			break;
		if ((*p) == 'I' || (*p) == 'S' || (*p) == 'C') {
			ch = (*p);
			for (; p < lim && !isnum(*p); ++p)
				;
			for (V = 0; p < lim && isnum(*p); ++p)
				V = V * 10 + (*p) - '0';

			k = search(A, V);
			if (ch == 'I') {
				if (X[k] == 0)
					X[k] = 1, update(1, 1, A[0], k);
			}
			else if (ch == 'S') {
				if (X[k] == 1)
					X[k] = 0, update(1, 1, A[0], k);
				else
					printf("-1\n");
			}
			else
				printf("%d\n", X[k]);
		} else {
			if (T[1] > 1) {
				if ((*(p + 1)) == 'A') 	/* MAX */
					printf("%d\n", MaxDif[1]);
				else
					printf("%d\n", MinDif[1]);
			} else
				printf("-1\n");
			p += 3;
		}
	}			

	return 0;
}