Cod sursa(job #2032551)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 5 octombrie 2017 12:16:38
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fi("secv8.in");
ofstream fo("secv8.out");

struct T {
	int siz, key, pr;
	bool rev;
	T *st, *dr; } *nil;

int n, junk;
T *root;

void reset(T *nod) {
	nod->siz = nod->st->siz + 1 + nod->dr->siz; }

void prop(T *nod) {
	if (nod->rev) {
		nod->rev = 0;
		nod->st->rev^= 1;
		nod->dr->rev^= 1;
		swap(nod->st, nod->dr); } }

T *join(T *a, T *b) {
	if (a == nil) return b;
	if (b == nil) return a;

	prop(a);
	prop(b);

	if (a->pr >= b->pr) {
		a->dr = join(a->dr, b);
		reset(a), reset(b);
		prop(a);
		return a; }
	else {
		b->st = join(a, b->st);
		reset(b), reset(a);
		prop(b);
		return b; } }

T *kth(T *nod, int pos) {
	prop(nod);
	if (nod == nil || pos == nod->st->siz)
		return nod;

	if (nod->st->siz > pos)
		return kth(nod->st, pos);
	else
		return kth(nod->dr, pos - nod->st->siz - 1); }

pair<T*, T*> split(T *nod, int pos) {
	if (nod == nil) 
		return {nil, nil};

	prop(nod);

	if (nod->st->siz == pos) {
		auto t = nod->st;
		nod->st = nil;
		reset(nod);
		return {t, nod}; }

	else if (nod->st->siz > pos) {
		auto t = split(nod->st, pos);
		nod->st = t.second;
		reset(nod);
		prop(nod);
		return {t.first, nod}; }

	else {
		auto t = split(nod->dr, pos - nod->st->siz - 1);
		nod->dr = t.first;
		reset(nod);
		prop(nod);
		return {nod, t.second}; } }

T *join3(T *a, T *b, T *c) {
	return join(join(a, b), c); }

tuple<T*, T*, T*> split3(T *nod, int a, int b) {
	auto tst = split(nod, a);
	auto tdr = split(tst.second, b - a);
	
	return tuple<T*, T*, T*>(tst.first, tdr.first, tdr.second); }

void dfs(T *nod) {
	prop(nod);
	if (nod == nil)
		return;

	dfs(nod->st);
	fo << nod->key << ' ';
	dfs(nod->dr); }

int main() {
	srand(time(0));
	nil = new T; *nil = {0, 0, -1, false, nil, nil};
	root = nil;

	int p, v, l, r;
	char op;

	fi >> n >> junk;
	while (n--) {
		fi >> op;
		switch (op) {
		case 'I': {
			fi >> p >> v; --p;
			auto s = split(root, p);
			root = join3(s.first, new T {1, v, rand(), false, nil, nil}, s.second);
			break; }

		case 'R': {
			fi >> l >> r; --l;
			auto t = split3(root, l, r);
			get<1>(t)->rev^= 1;
			root = join3(get<0>(t), get<1>(t), get<2>(t));
			break; }

		case 'A': {
			fi >> p; --p;
			fo << kth(root, p)->key << '\n';
			break; }

		case 'D': {
			fi >> l >> r; --l;
			auto tmp = split3(root, l, r);
			root = join(get<0>(tmp), get<2>(tmp));
			break; } } }

	dfs(root);
	fo << '\n';

	return 0; }