Cod sursa(job #2470983)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 9 octombrie 2019 22:50:17
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.97 kb
#include <bits/stdc++.h>
using namespace std;

const int INF = 1000000000;

struct Node {
	bool rev;
	int key, pri, siz;
	Node *lson, *rson;

	Node(int _key = 0, int _pri = -1, int _siz = 0, bool _rev = false, Node* _lson = NULL, Node* _rson = NULL) :
		key(_key), pri(_pri), siz(_siz), rev(_rev), lson(_lson), rson(_rson) {}
} *root, *nil;

int myRand(void) {
	return 1LL * rand() * rand() % INF;
}

void reset(Node *&node) {
	if (node == nil)
		return;
	node -> siz = node -> lson -> siz + node -> rson -> siz + 1;
	if (node -> rev) {
		swap(node -> lson, node -> rson);
		if (node -> lson != nil)	
			node -> lson -> rev ^= true;
		if (node -> rson != nil)
			node -> rson -> rev ^= true;
		node -> rev = false;
	}
}

void rotateLeft(Node *&node) {
	reset(node);
	reset(node -> lson);
	Node *aux = node -> lson;
	node -> lson = aux -> rson;
	aux -> rson = node; node = aux;
	reset(node -> rson);
	reset(node);
}

void rotateRight(Node *&node) {
	reset(node);
	reset(node -> rson);
	Node *aux = node -> rson;
	node -> rson = aux -> lson;
	aux -> lson = node; node = aux;
	reset(node -> lson);
	reset(node);
}

void balance(Node *&node) {
	reset(node);
	if (node -> lson -> pri > node -> pri)
		reset(node -> lson), rotateLeft(node);
	else
	if (node -> rson -> pri > node -> pri)
		reset(node -> rson), rotateRight(node);
}

void insert(Node *&node, int key, int pri, int siz) {
	reset(node);
	if (node == nil)
		node = new Node(key, pri, 1, false, nil, nil);
	else {
		if (node -> lson -> siz + 1 >= siz)
			insert(node -> lson, key, pri, siz);
		else
			insert(node -> rson, key, pri, siz - node -> lson -> siz - 1);
		balance(node);
	}
}

void erase(Node *&node, int siz) {
	reset(node);
	if (node -> lson == nil and node -> rson == nil)
		delete node, node = nil;
	else {
		if (node -> lson -> siz > siz)
			erase(node -> lson, siz);
		else if (node -> lson -> siz + 1 < siz)
			erase(node -> rson, siz - node -> lson -> siz - 1);
		else {
			if (node -> lson -> pri >= node -> rson -> pri) {
				rotateLeft(node);
				erase(node -> rson, node -> rson -> lson -> siz + 1);
			} else {
				rotateRight(node); 
				erase(node -> lson, node -> lson -> lson -> siz + 1);
			}
		}
		balance(node);
	}
}

Node* join(Node *treap1, Node *treap2) {
	Node *aux = new Node(0, -INF, treap1 -> siz + treap2 -> siz + 1, false, treap1, treap2);
	erase(aux, treap1 -> siz + 1);
	return aux;
}

pair<Node*, Node*> split(Node *treap, int siz) {
	insert(treap, -1, INF, siz + 1);
	return make_pair(treap -> lson, treap -> rson);
}

int access(Node *node, int siz) {
	reset(node);
	if (node -> lson -> siz + 1 == siz)
		return node -> key;
	else {
		if (node -> lson -> siz >= siz)
			return access(node -> lson, siz);
		else
			return access(node -> rson, siz - node -> lson -> siz - 1);
	}
}

void reverse(Node *&treap, int le, int ri) {
	pair<Node*, Node*> split1 = split(treap, ri);
	pair<Node*, Node*> split2 = split(split1.first, le - 1);
	split2.second -> rev = true;
	split1.first = join(split2.first, split2.second);
	treap = join(split1.first, split1.second);
}

void eliminate(Node *&treap, int le, int ri) {
	pair<Node*, Node*> split1 = split(treap, ri);
	pair<Node*, Node*> split2 = split(split1.first, le - 1);
	treap = join(split2.first, split1.second);
}

void dfs(Node *&node) {
	reset(node);
	if (node == nil)
		return;
	dfs(node -> lson);
	printf("%d ", node -> key);
	dfs(node -> rson);
}
	
int main(void) {
	freopen("secv8.in", "r", stdin);
	freopen("secv8.out", "w", stdout);
	root = nil = new Node();
	nil -> lson = nil -> rson = nil;
	srand(unsigned(time(0)));
	int q, inutil;
	scanf("%d %d", &q, &inutil);
	while (q--) {
		char ch;
		scanf("\n%c", &ch);
		if (ch == 'I') {
			int k, e;
			scanf("%d %d", &k, &e);
			insert(root, e, myRand(), k);
		} else 
		if (ch == 'A') {
			int k;
			scanf("%d", &k);
			printf("%d\n", access(root, k));
		} else	
		if (ch == 'R') {
			int le, ri;
			scanf("%d %d", &le, &ri);
			reverse(root, le, ri);
		} else {
			int le, ri;
			scanf("%d %d", &le, &ri);
			eliminate(root, le, ri);
		}
	}
	dfs(root);
	return 0;
}