Cod sursa(job #1491286)

Utilizator aimrdlAndrei mrdl aimrdl Data 25 septembrie 2015 00:59:18
Problema Zeap Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.49 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <vector>

using namespace std;

typedef struct cell {
	int v;
	struct cell *prev;
	vector <struct cell *> next;
} SCell, *SList;

SList val, diff;
SList lastVal;

inline int rnd () {
	int s = 1;
	while (rand() % 2) {
		++s;
	}
	
	return s;
}

int find (int x, SList sL) {
	if (!sL) return 0;
	
	int level = sL->next.size() - 1;
	
	while (level >= 0) {
		while (sL->next[level] && sL->next[level]->v <= x) {
			sL = sL->next[level];
			level = sL->next.size() - 1;
		}
		
		--level;
	}
	
	if (sL->v == x) {
		return 1;
	}
	
	return 0;	
}

inline SList newNode (int x, int *g) {
	SList node = (SList) calloc(1, sizeof(SCell));
	*g = rnd();
	node->v = x;
	node->next.resize(*g, NULL);
	return node;
}

int add (int x, SList *asL, bool changeDiff) {
	if (*asL == val) {
		if (find (x, *asL)) return 0;
	}
	
	int g;
	SList node = newNode(x, &g);
	--g;
	
	if (!(*asL)) {
		*asL = node;
		return 1;
	} else if ((*asL)->v >= x) {
		for (int i = 0; i <= g; ++i) {
			node->next[i] = *asL;
		}
		(*asL)->prev = node;
		*asL = node;
	} else {	
		SList sL = *asL;

		int level = sL->next.size() - 1;
		while (level >= 0) {
			while (sL->next[level] && sL->next[level]->v <= x) {
				sL = sL->next[level];
				level = sL->next.size() - 1;
			}
		
			if (sL->v == x) return 0;
			
			if (level <= g) {
				node->next[level] =  sL->next[level];
				sL->next[level] = node;
				if (level == 0) node->prev = sL;
			}
				
			--level;
		}
	}
	
	if (changeDiff) {
		if (node->next[0]) add(node->next[0]->v - node->v, &diff, false);
		if (node->prev) add(node->v - node->prev->v, &diff, false);
	}
	
	return 1;
}

int remove (int x, SList *asL, bool changeDiff) {
	if (!(*asL) || !find(x, *asL)) return 0;
	
	SList sL = *asL;
	
	if (sL->v == x) {
		if (sL->next[0]) sL->next[0]->prev = NULL;
		*asL = sL->next[0];
		if (changeDiff) {
			if (sL->next[0]) remove(sL->next[0]->v - sL->v, &diff, false);
		}
		
		free(sL);
	} else {	
		int level = sL->next.size() - 1, pre = level;
		SList temp;
		while (level >= 0) {
			while (sL->next[level] && sL->next[level]->v <= x) {
				temp = sL;
				pre = level;
				sL =  sL->next[level];
				level = sL->next.size() - 1;
			}
		
			if (level == 0 && sL->next[0]) {
				sL->next[0]->prev = sL->prev;
			}
		
			temp->next[pre] = sL->next[level];
			--level;
		}
		
		if (changeDiff) {
			if (sL->next[0]) remove(sL->next[0]->v - sL->v, &diff, false);
			if (sL->prev) remove(sL->v - sL->prev->v, &diff, false);
			if (sL->next[0] && sL->prev)	add(sL->next[0]->v - sL->prev->v, &diff, false);
		}
		
		free(sL);
	}	
	
	return 1;
}

int last (SList sL) {
	if (!sL) return -1;
	
	int level = sL->next.size() - 1;
	
	while (level >= 0) {
		while (sL->next[level]) {
			sL = sL->next[level];
			level = sL->next.size() - 1;
		}
		
		--level;
	}
	
	return sL->v;
}
	
int main(void) {
	srand(time(NULL));
	freopen("zeap.in", "r", stdin);
	freopen("zeap.out", "w", stdout);
	
	char buffer[1000];
	while (fgets(buffer, 1000, stdin)) {
		if (buffer[0] == 'I') {
			add(atoi(buffer+2), &val, true);
		} else if (buffer[0] == 'S') {
			int test = remove (atoi(buffer+2), &val, true);
			if (!test) printf("-1\n");
		} else if (buffer[0] == 'C') {
			printf("%d\n", find(atoi(buffer+2), val));
		} else if (buffer[1] == 'A') {
			if (val->next[0]) {
				printf("%d\n", last(val) - val->v);
			} else {
				printf("-1\n");
			}
		} else if (buffer[1] == 'I') {
			if (val->next[0]) {
				printf("%d\n", diff->v);
			} else {
				printf("-1\n");
			}
		}
	}
		
	return 0;
}