Cod sursa(job #1738967)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 8 august 2016 12:11:13
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <bits/stdc++.h>
using namespace std;

struct nod{
	int key, size, prior, flip;
	nod *l, *r; } nil {};

void rec_del(nod *n){
	if(n == &nil){
		return; }
	rec_del(n->l), rec_del(n->r);
	delete n; }

void reset(nod *n){
	n->size = n->l->size + n->r->size + 1; }

void prop(nod *n){
	if(n->flip){
		n->flip = 0;
		swap(n->l, n->r);
		n->l->flip ^= 1;
		n->r->flip ^= 1; } }

void dfs(nod *n, ostream& g){
	if(n == &nil){
		return; }
	prop(n);
	dfs(n->l, g);
	g << n->key << ' ';
	dfs(n->r, g); }

nod *join(nod *l, nod *r){
	if(l == &nil){
		return r; }
	if(r == &nil){
		return l; }
	prop(l), prop(r);
	if(l->prior >= r->prior){
		l->r = join(l->r, r);
		reset(l);
		return l; }
	else{
		r->l = join(l, r->l);
		reset(r);
		return r; } }

pair<nod*, nod*> split(nod *n, const int poz){
	if(n == &nil){
		return make_pair(&nil, &nil); }
	prop(n);
	if(n->l->size == poz){
		pair<nod*, nod*> rez {n->l, n};
		n->l = &nil;
		reset(rez.second);
		return rez; }
	else if(n->l->size < poz){
		pair<nod*, nod*> other = split(n->r, poz - n->l->size - 1);
		n->r = other.first;
		other.first = n;

		reset(other.first);
		return other; }
	else{
		pair<nod*, nod*> other = split(n->l, poz);
		n->l = other.second;
		other.second = n;

		reset(other.second);
		return other; } }

nod *insert(nod *n, const int poz, const int key){
	pair<nod*, nod*> p = split(n, poz);

	nod *rez = new nod;
	*rez = nod { key, 1, rand(), 0, &nil, &nil };

	return join(join(p.first, rez), p.second); }

tuple<nod*, nod*, nod*> three_way_split(nod *n, const int p1, const int p2){
	pair<nod*, nod*> p = split(n, p2);
	pair<nod*, nod*> _p = split(p.first, p1);
	return make_tuple(_p.first, _p.second, p.second); }

nod *erase(nod *n, const int p1, const int p2){
	auto p = three_way_split(n, p1, p2);
	rec_del(get<1>(p));
	return join(get<0>(p), get<2>(p)); }

nod *reverse(nod *n, const int p1, const int p2){
	auto p = three_way_split(n, p1, p2);
	get<1>(p)->flip ^= 1;
	return join(join(get<0>(p), get<1>(p)), get<2>(p)); }

int access(nod *n, const int poz){
	prop(n);
	if(n->l->size == poz){
		return n->key; }
	else if(n->l->size > poz){
		return access(n->l, poz); }
	else{
		return access(n->r, poz - n->l->size - 1); } }

int main(){
	srand(time(nullptr));
	ifstream f("secv8.in");
	ofstream g("secv8.out");
	int n, useless;

	f >> n >> useless;

	nod *rad = &nil;

	for(int poz, key, p1, p2; n--; ){
		char ch;
		f >> ch;
		if(ch == 'I'){
			f >> poz >> key;
			rad = insert(rad, poz-1, key); }
		else if(ch == 'A'){
			f >> poz;
			g << access(rad, poz-1) << '\n'; }
		else if(ch == 'R'){
			f >> p1 >> p2;
			rad = reverse(rad, p1-1, p2); }
		else{
			f >> p1 >> p2;
			rad = erase(rad, p1-1, p2); } }

	dfs(rad, g);

	rec_del(rad);
	return 0; }