Cod sursa(job #1960994)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 10 aprilie 2017 20:24:10
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <fstream>
#include <iostream>
#include <random>
#include <ctime>
using namespace std;

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

typedef struct Treap * Arbore;
typedef pair <Arbore, Arbore> Paa;
Arbore NIL;
struct Treap
{
	int g, prio, val;
	bool lazy;
	Arbore st, dr;
	Treap(int _val = 0) : lazy(0), g(1), prio(rand()), val(_val), st(NIL), dr(NIL) { }
	~Treap()
	{
		if (st != NIL)
			delete st;
		if (dr != NIL)
			delete dr;
	}
};

Arbore join(Arbore a, Arbore b);
pair <Arbore, Arbore> split(Arbore k, int poz);
void propagate(Arbore k);
Arbore insert(Arbore k, int val, int poz);
Arbore reverse(Arbore k, int st, int dr);
int nelement(Arbore k, int poz);
Arbore scoate(Arbore k, int st, int dr);
void parcurge(Arbore k);
void reset(Arbore k);

int main()
{
	srand(time(0));
	NIL = new Treap();
	NIL->st = NIL->dr = NIL;
	NIL->g = 0;
	Arbore k = NIL;

	int n, q;
	char op;
	int a, b;
	in >> n >> q;

	while (n--) {
		in >> op;
		if (op == 'I') {
			in >> a >> b;
			k = insert(k, b, a);
		}
		else if (op == 'A') {
			in >> a;
			out << nelement(k, a) << '\n';
		}
		else if (op == 'D') {
			in >> a >> b;
			k = scoate(k, a, b);
		}
		else {
			in >> a >> b;
			k = reverse(k, a, b);
		}
	}
	parcurge(k);
	return 0;
}

void reset(Arbore k)
{
	k->g = 1 + k->st->g + k->dr->g;
}

void parcurge(Arbore k)
{
	propagate(k);
	if (k == NIL)
		return;
	parcurge(k->st);
	out << k->val << ' ';
	parcurge(k->dr);
}

int nelement(Arbore k, int poz)
{
	propagate(k);
	if (poz == k->st->g + 1)
		return k->val;
	if (poz <= k->st->g)
		return nelement(k->st, poz);
	return nelement(k->dr, poz - 1 - k->st->g);
}

Arbore insert(Arbore k, int val, int poz)
{
	Arbore a = new Treap(val);
	Paa s(split(k, poz));
	return join(s.first, join(a, s.second));
}

Arbore reverse(Arbore k, int st, int dr)
{
	Paa s1(split(k, dr + 1));
	Paa s2(split(s1.first, st));
	s2.second->lazy ^= 1;
	return join(s2.first, join(s2.second, s1.second));
}

Arbore scoate(Arbore k, int st, int dr)
{
	Paa s1(split(k, dr + 1));
	Paa s2(split(s1.first, st));
	return join(s2.first, s1.second);
}

void propagate(Arbore k)
{
	if (k == NIL)
		return;
	if (k->lazy) {
		swap(k->st, k->dr);
		k->st->lazy ^= 1;
		k->dr->lazy ^= 1;
		k->lazy = 0;
	}
}

Paa split(Arbore k, int poz)
{
	propagate(k);
	if (k == NIL)
		return { NIL, NIL };
	if (poz <= k->st->g) {
		Paa x(split(k->st, poz));
		k->st = x.second;
		reset(k);
		return { x.first, k };
	}
	if (poz == 1 + k->st->g) {
		Paa x({ k->st, k });
		k->st = NIL;
		reset(k);
		return x;
	}
	Paa x(split(k->dr, poz - 1 - k->st->g));
	k->dr = x.first;
	reset(k);
	return { k, x.second };
}

Arbore join(Arbore a, Arbore b)
{
	propagate(a);
	propagate(b);
	if (a == NIL)
		return b;
	if (b == NIL)
		return a;
	if (a->prio >= b->prio) {
		a->dr = join(a->dr, b);
		reset(a);
		return a;
	}
	b->st = join(a, b->st);
	reset(b);
	return b;
}