Cod sursa(job #2638350)

Utilizator LucaDantasLuca Dantas LucaDantas Data 27 iulie 2020 21:20:07
Problema Zeap Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.58 kb
#include<bits/stdc++.h>
using namespace std;

constexpr int inf = 0x3f3f3f3f;

std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count() ^ (long long) (make_unique<char>().get()));

template<typename T> T rnd(T v) {
  T k;
  k = (T) rng();
  return (T) (((k % v) + v) % v);
}


struct Treap
{
	struct Node {
		int val, pri, first, last, tam; // menor e maior diferenca na subarvore
		Node *l, *r;
		Node() {}
		Node(int v) : val(v), pri(rnd(inf)), first(v), last(v), tam(1), l(NULL), r(NULL) {}
	} *root;

	Treap() : root(NULL) {}

	int size(Node* node) {return node==NULL?0:node->tam;}
	void upd(Node* node) {
		if(node == NULL) return;
		node->tam = size(node->l) + size(node->r) + 1;
		
		if(node->l != NULL) node->first = node->l->first;
		else node->first = node->val;
		
		if(node->r != NULL) node->last = node->r->last;
		else node->last = node->val;
	}

	void split(Node* node, int v, Node *&a, Node *&b) {
		if(node == NULL) {a = b = NULL; return;}
		if(node->val <= v) {
			split(node->r, v, node->r, b);
			a = node; upd(a);
		} else {
			split(node->l, v, a, node->l);
			b = node; upd(b);
		}
	}

	Node* merge(Node* l, Node* r) {
		if(l == NULL) return r;
		if(r == NULL) return l;
		if(l->pri > r->pri) {
			l->r = merge(l->r, r);
			upd(l); return l;
		}
		r->l = merge(l, r->l);
		upd(r); return r;
	}

	int menor(Node* node) {
		if(node==NULL || size(node) == 1) return inf;

		if(node->l == NULL) {
			assert(node->r);
			return min(abs(node->val - node->r->first), menor(node->r));
		}

		if(node->r == NULL) {
			assert(node->l);
			return min(abs(node->val - node->l->last), menor(node->l));
		}

		return min({abs(node->val - node->r->first), abs(node->val - node->l->last), menor(node->l), menor(node->r)});
	}

	int maior(Node* node) {
		return node->last - node->first;
	}

	void print() {
		_print(root); printf("\n");
	}

	void _print(Node* node) {
		if(node==NULL) return;
		_print(node->l);
		printf("%d ", node->val);
		_print(node->r);
	}

	void split_pos(Node* node, int pos, Node *&a, Node*&b) {
		if(node == NULL) {a = b = NULL; return;}
		if(size(node->l) <= pos) {
			split_pos(node->r, pos - size(node->l) - 1, node->r, b);
			a = node; upd(a);
		} else {
			split_pos(node->l, pos, a, node->l);
			b = node; upd(b);
		}
	}

	pair<int, int> query(int i, int j) {
		pair<int, int> ans;
		Node *a, *b, *c = NULL;

		split_pos(root, i-1, a, b);
		split_pos(b, j-i, b, c);

		if(size(b) > 1) {
			ans.first = menor(b);
			ans.second = maior(b);
		} else ans = {-1, -1};

		root = merge(a, b);
		root = merge(root, c);

		return ans;
	}

	bool count(Node* node, int k) {
		if(!node) return 0;
		if(node->val == k) return 1;
		if(node->val > k) return count(node->l, k);
		return count(node->r, k);
	}

	void insert(int val) {
		if(count(root, val)) return;
		Node *a, *b;
		Node *c = new Node(val);
		split(root, val, a, b);
		root = merge(a, c);
		root = merge(root, b);
	}

	void erase(int val) {
		Node *a, *b;
		split(root, val, a, b);
		split(a, val-1, root, a);
		delete(a);
		root = merge(root, b);
	}
};

int main() {
	Treap t;

	freopen("zeap.in", "r", stdin);
	freopen("zeap.out", "w", stdout);

	ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
	// int n; scanf("%d", &n);
	int n; cin >> n;
	while(n--) {
		int x; char op; //scanf(" %c %d", &op, &x);
		cin >> op >> x;
		if(op == 'I') t.insert(x);
		else if(op == 'D') t.erase(x);
		else {
			int y; // scanf("%d", &y);
			cin >> y;
			pair<int, int> ans = t.query(x, y);
			if(op == 'X') //printf("%d\n", ans.second);
				cout << ans.second << '\n';
			else //printf("%d\n", ans.first);
				cout << ans.first << '\n';
		}
	}
}