Cod sursa(job #385746)

Utilizator raduzerRadu Zernoveanu raduzer Data 23 ianuarie 2010 13:35:40
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#include <cstdio>
#include <ctime>
#include <cstdlib>
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAX = 1000000000;

struct treap{
	int d, v, p, r;
	treap *st, *dr;
} *r, *nil;

int n;

treap *rot_st(treap *r)
{
	treap *aux;

	aux = r->dr;

	r->dr = aux->st;
	aux->st = r;
	r->d = r->st->d + r->dr->d + 1;

	return aux;;
}

treap *rot_dr(treap *r)
{
	treap *aux;

	aux = r->st;

	r->st = aux->dr;
	aux->dr = r;
	r->d = r->st->d + r->dr->d + 1;

	return aux;
}

void rev(treap *r)
{
	if (r->r)
	{
		if (r->st != nil)
			r->st->r ^= 1;
		if (r->dr != nil)
			r->dr->r ^= 1;

		r->r = 0;

		treap *aux;

		aux = r->dr;
		r->dr = r->st;
		r->st = aux;
	}
}

treap *insert(treap *r, int p, int v, int k)
{
	if (r == nil)
		return r = new treap{1, v, k, 0, nil, nil};

	rev(r);
	rev(r->st);
	rev(r->dr);

	if (p <= r->st->d + 1 || (r->d == 1 && p <= 1))
	{
		r->st = insert(r->st, p, v, k);

		if (r->st->p > r->p)
			r = rot_dr(r);
	}
	else
	{
		r->dr = insert(r->dr, p - r->st->d - 1, v, k);

		if (r->dr->p > r->p)
			r = rot_st(r);
	}

	r->d = r->st->d + r->dr->d + 1;

	return r;
}

treap *query(treap* r, int p)
{
	rev(r);
	rev(r->st);
	rev(r->dr);

	if (r->st->d + 1 == p)
		return r;

	if (p <= r->st->d)
		return query(r->st, p);
	return query(r->dr, p - r->st->d - 1);
}

treap *erase(treap *r)
{
	rev(r);
	rev(r->st);
	rev(r->dr);

	if (r->st == nil && r->dr == nil)
	{
		delete r;
		return r = nil;
	}

	if (r->st->p > r->dr->p)
	{
		r = rot_dr(r);
		r->dr = erase(r->dr);
	}
	else
	{
		r = rot_st(r);
		r->st = erase(r->st);
	}

	r->d = r->st->d + r->dr->d + 1;

	return r;
}

void split(treap *r, int p, treap *&nod1, treap *&nod2)
{
	treap *aux;
	aux = insert(r, p, 0, INF);

	nod1 = aux->st;
	nod2 = aux->dr;
}

treap *join(treap *r1, treap *r2)
{
	treap *aux;
	aux = new treap;
	*aux = *nil;

	aux->st = r1;
	aux->dr = r2;
	aux->d = r1->d + r2->d + 1;

	erase(aux);
}

treap *reverse(treap *r, int x1, int x2)
{
	treap *nod1, *nod2, *nod3, *nod4;

	split(r, x1, nod1, nod2);
	split(nod2, x2 - x1 + 2, nod3, nod4);

	nod3->r ^= 1;

	return r = join(nod1, join(nod3, nod4));
}

treap *del(treap *r, int x1, int x2)
{
	treap *nod1, *nod2, *nod3, *nod4;

	split(r, x1, nod1, nod2);
	split(nod2, x2 - x1 + 2, nod3, nod4);

	return r = join(nod1, nod4);
}

void print(treap *r)
{
	if (r == nil)
		return;

	rev(r);
	rev(r->st);
	rev(r->dr);

	print(r->st);
	printf("%d ", r->v);
	print(r->dr);
}

int main()
{
	int i, j, w, x1, x2;

	srand(time(0));

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

	nil = new treap{0, 0, 0, 0, NULL, NULL};
	r = nil;

	scanf("%d %d", &n, &w);


	for (i = 1; i <= n; ++i)
	{
		int x1, x2;
		char ch;
		scanf(" %c", &ch);
		
		if (ch == 'I')
		{
			scanf("%d %d", &x1, &x2);
			r = insert(r, x1, x2, rand() % MAX + 1);
		}

		if (ch == 'A')
		{
			scanf("%d", &x1);
			printf("%d\n", query(r, x1)->v);
		}

		if (ch == 'R')
		{
			scanf("%d %d", &x1, &x2);
			r = reverse(r, x1, x2);
		}

		if (ch == 'D')
		{
			scanf("%d %d", &x1, &x2);
			r = del(r, x1, x2);
		}
	}

	print(r);
}