Cod sursa(job #1960978)

Utilizator theodor.moroianuTheodor Moroianu theodor.moroianu Data 10 aprilie 2017 20:07:20
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.01 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);

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 parcurge(Arbore 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, st));
	Paa s2(split(s1.second, dr - st + 2));
	s2.first->lazy ^= 1;
	return join(s1.first, join(s2.first, s2.second));
}

Arbore scoate(Arbore k, int st, int dr)
{
	Paa s1(split(k, st));
	Paa s2(split(s1.second, dr - st + 2));
	if (s2.first != NIL)
		delete s2.first;
	return join(s1.first, s2.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 = NIL;
		k->g = 1 + k->dr->g;
		return { x.first, join(x.second, k) };
	}
	if (poz == 1 + k->st->g) {
		Paa x({ k->st, k });
		k->g = 1 + k->dr->g;
		k->st = NIL;
		return x;
	}
	Paa x(split(k->dr, poz - 1 - k->st->g));
	k->dr = NIL;
	k->g = 1 + k->st->g;
	return { join(k, x.first), 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);
		a->g = a->dr->g + a->st->g + 1;
		return a;
	}
	b->st = join(a, b->st);
	b->g = 1 + b->st->g + b->dr->g;
	return b;
}