Cod sursa(job #1491224)

Utilizator aimrdlAndrei mrdl aimrdl Data 24 septembrie 2015 22:50:36
Problema Zeap Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.62 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <vector>

using namespace std;

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

SList val, diff;

inline int rnd () {
	unsigned int s = 1;	
	while (rand() % 2 == 0) {
		++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);
	node->prev.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) {
		if ((unsigned int) g > (*asL)->prev.size() - 1) g = (*asL)->prev.size() - 1;
		for (int i = 0; i <= g; ++i) {
			node->next[i] = *asL;
			(*asL)->prev[i] = 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 (level <= g) {
				node->next[level] =  sL->next[level];
				sL->next[level] = node;
				node->prev[level] = sL;
			}
				
			--level;
		}
	}
	
	if (changeDiff) {
		if (node->next[0]) add(node->next[0]->v - node->v, &diff, false);
		if (node->prev[0]) add(node->v - node->prev[0]->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) {
		for (unsigned int i = 0; i < sL->next.size(); ++i) {
			if (sL->next[i]) sL->next[i]->prev[i] = 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;
		while (level >= 0) {
			while (sL->next[level] && sL->next[level]->v <= x) {
				sL =  sL->next[level];
				level = sL->next.size() - 1;
			}
		
				if (sL->next[level]) {
					sL->next[level]->prev[level] = sL->prev[level];
				}
				
				if (sL->prev[level]) {
					sL->prev[level]->next[level] = sL->next[level];
				}
		
			--level;
		}
		
		if (changeDiff) {
			if (sL->next[0]) remove(sL->next[0]->v - sL->v, &diff, false);
			if (sL->prev[0]) remove(sL->v - sL->prev[0]->v, &diff, false);
			if (sL->next[0] && sL->prev[0])	add(sL->next[0]->v - sL->prev[0]->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;
}