Cod sursa(job #2446997)

Utilizator radustn92Radu Stancu radustn92 Data 11 august 2019 14:37:00
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.56 kb
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <algorithm>

struct item {
	int value, priority, cnt;
	bool reversed;

	item* l;
	item* r;

	item() {
	}

	item(int _value, int _priority) {
		value = _value;
		priority = _priority;
		cnt = 1;
		l = r = NULL;
		reversed = false;
	}

	void reverse() {
		reversed ^= true;
	}	
};
typedef item* pitem;

int getCnt(pitem t) {
	return t != NULL ? t -> cnt : 0;
}

void updateCnt(pitem t) {
	if (t != NULL) {
		t -> cnt = 1 + getCnt(t -> l) + getCnt(t -> r);
	}
}

void pushUpdates(pitem t) {
	if (t == NULL) {
		return;
	}

	if (t -> reversed) {
		t -> reversed = false;
		std::swap(t -> l, t -> r);
		if (t -> l != NULL) {
			t -> l -> reverse();
		}
		if (t -> r != NULL) {
			t -> r -> reverse();
		}
	}
}

// interval [key, N) will be in r. [0, key) will be in l
void split(pitem t, pitem& l, pitem& r, int key, int add = 0) {
	if (t == NULL) {
		l = r = NULL;
		return;
	}
	pushUpdates(t);

	int currKey = add + getCnt(t -> l);
	if (key <= currKey) {
		split(t -> l, l, t -> l, key, add);
		r = t;
	} else {
		split(t -> r, t -> r, r, key, currKey + 1);
		l = t;
	}

	updateCnt(t);
}

void merge(pitem& t, pitem l, pitem r) {
	if (l == NULL || r == NULL) {
		t = (l == NULL) ? r : l;
		return;
	}
	pushUpdates(l);
	pushUpdates(r);

	if (l -> priority > r -> priority) {
		merge(l -> r, l -> r, r);
		t = l;
	} else {
		merge(r -> l, l, r -> l);
		t = r;
	}

	updateCnt(t);
}

void insert(pitem& t, int pos, int value) {
	pitem zeroToPosMinus1, posToN;
	split(t, zeroToPosMinus1, posToN, pos);

	pitem newItem = new item(value, rand());
	merge(t, zeroToPosMinus1, newItem);
	merge(t, t, posToN);
}

pitem search(pitem t, int key, int add = 0) {
	if (t == NULL) {
		return NULL;
	}
	pushUpdates(t);

	int currKey = add + getCnt(t -> l);
	if (currKey == key) {
		return t;
	}
	if (key < currKey) {
		return search(t -> l, key, add);
	}
	return search(t -> r, key, currKey + 1);
}

void debug(pitem t) {
	if (t == NULL) {
		return;
	}
	pushUpdates(t);

	debug(t -> l);
	printf("%d ", t -> value);
	debug(t -> r);
}

void printArray(pitem root) {
	debug(root);
	printf("\n");
}

void deleteRange(pitem& t, int from, int to) {
	pitem L, mid, R;
	split(t, L, R, from);
	split(R, mid, R, to - from + 1);

	merge(t, L, R);
}

void reverseRange(pitem& t, int from, int to) {
	pitem L, mid, R;
	split(t, L, R, from);
	split(R, mid, R, to - from + 1);

	mid -> reverse();
	merge(t, L, mid);
	merge(t, t, R);
}

int main() {
	freopen("secv8.in", "r", stdin);
	freopen("secv8.out", "w", stdout);

	pitem root = NULL;
	srand(time(0));
	
	int operations, reverseExists;
	scanf("%d%d", &operations, &reverseExists);
	char* opType = new char[2];
	for (int operation = 0; operation < operations; operation++) {
		scanf("%s", opType);
		switch (opType[0]) {
			case 'I': {
				int k, value;
				scanf("%d%d", &k, &value);
				// printf("INSERT %d on pos %d\n", value, k);

				insert(root, k - 1, value);
				// printArray(root);
				break;
			}
			case 'A': {
				int k;
				scanf("%d", &k);
				// printf("ACCESS %d\n", k);

				pitem kThElement = search(root, k - 1);
				assert(kThElement != NULL);
				printf("%d\n", kThElement -> value);
				break;
			}
			case 'R': {
				int from, to;
				scanf("%d%d", &from, &to);

				// printf("REVERSE %d %d\n", from, to);
				reverseRange(root, from - 1, to - 1);

				// printArray(root);
				break;
			}
			case 'D': {
				int from, to;
				scanf("%d%d", &from, &to);
				// printf("DELETE %d %d\n", from, to);

				deleteRange(root, from - 1, to - 1);

				// printArray(root);
				break;
			}
		}
	}

	printArray(root);
	return 0;
}