Cod sursa(job #940818)

Utilizator crushackPopescu Silviu crushack Data 17 aprilie 2013 09:36:06
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.32 kb
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#define oo (1<<31)-1
using namespace std;

const char IN[]="secv8.in",OUT[]="secv8.out";

struct treap{
	int nr,key,cnt;
	bool change;
	treap *l,*r;
} *T,*NIL;

int N,K;

void init(){
	NIL=(treap*)malloc(sizeof(treap));
	NIL->key=NIL->cnt=0;
	NIL->l=NIL->r=NIL;
	NIL->change=0;
	T=NIL;
}

void din(treap* &n){
	n->cnt=n->l->cnt + n->r->cnt + 1;
}

void propag(treap* &n){
	if (n->change){
		swap(n->l,n->r);
		n->l->change^=1;
		n->r->change^=1;
		n->change=0;
	}
}

void rotright(treap* &n){
	propag(n);propag(n->l);propag(n->r);
	treap *t=n->l;
	n->l=t->r;
	t->r=n;
	din(n);din(t);
	n=t;
}

void rotleft(treap* &n){
	propag(n);propag(n->l);propag(n->r);
	treap *t=n->r;
	n->r=t->l;
	t->l=n;
	din(n);din(t);
	n=t;
}

void balance(treap* &n){
	din(n);
	if (n->key < n->l->key)
		rotright(n);
	if (n->key < n->r->key)
		rotleft(n);
}

void add(treap* &n,int x,int poz,int key){

	propag(n);propag(n->l);propag(n->r);
	if (n==NIL){
		n=(treap*)malloc(sizeof(treap));
		n->key=key;
		n->nr=x;
		n->l=n->r=NIL;
		din(n);
		n->change=0;
		return;
	}

	if (n->cnt==1 && poz==2) add(n->r,x,poz,key);
	else if (n->cnt==1 && poz==1) add(n->l,x,poz,key);
	else if (n->l->cnt + 1<poz ) add(n->r,x,poz-n->l->cnt-1,key);
	else add(n->l,x,poz,key);

	balance(n);
	din(n);
}

int get(treap *n,int poz,int cpoz=0){

	propag(n);propag(n->l);propag(n->r);
	if (poz==cpoz+n->l->cnt+1)
		return n->nr;

	if (n->l->cnt + cpoz + 1<= poz)
		return get(n->r,poz,n->l->cnt + cpoz + 1);
	return get(n->l,poz,cpoz);
}

void write(treap *n){

	if (n==NIL) return;

	propag(n);
	write(n->l);
	printf("%d ",n->nr);
	write(n->r);
}

void erasen(treap* &n){

	propag(n);
	if (n->l==NIL && n->r==NIL){
		free(n);n=NIL;return;
	}

	if (n->l->key > n->r->key)
		rotright(n),erasen(n->r);
	else
		rotleft(n),erasen(n->l);
	din(n);
}

void erase(treap* &n,int poz,int cpoz=0){

	propag(n);propag(n->l);propag(n->r);
	if (n==NIL) return;

	if (poz==cpoz+n->l->cnt)
		erasen(n);
	else if (n->l->cnt + cpoz + 1<=poz) erase(n->r,poz,n->l->cnt + cpoz + 1);
	else erase(n->l,poz,cpoz);

}

void split(treap* &T,treap* &Ts,treap* &Td,int poz){
	add(T,-1,poz,oo);
	Ts=T->l;
	Td=T->r;
}

void reverse(int x,int y){

	treap *a,*b,*c,*d;

	propag(T);
	split(T,a,b,y+1);
	split(T->l,c,d,x);

	d->change^=1;

	erasen(T);
	erasen(T);
}

void eraseall(treap* &n){

	if (n==NIL) return;
	eraseall(n->r);
	eraseall(n->l);
	free(n);n=NIL;
}

void erase(int x,int y){

	treap *a,*b,*c,*d;

	propag(T);
	split(T,a,b,y+1);
	split(T->l,c,d,x);

	eraseall(T->l->r);
	din(T->l);din(T);

	erasen(T);
	erasen(T);
}

int main()
{
	int k,e,x,y;char c;
	freopen(IN,"r",stdin);
	scanf("%d%d",&N,&k);

	freopen(OUT,"w",stdout);
	init();
	while (N--){
		scanf(" %c",&c);
		if (c=='I'){ //Insert
			scanf("%d%d",&k,&e);
			add(T,e,k,rand()+1);
		}
		else if (c=='A'){ //access
			scanf("%d",&k);
			printf("%d\n",get(T,k));
		}
		else if (c=='R'){ //reverse
			scanf("%d%d",&x,&y);
			reverse(x,y);
		}
		else{ //delete
			scanf("%d%d",&x,&y);
			erase(x,y);
		}
		//printf("->");printf("%d->",T->cnt);write(T);printf("\n");
	}

	write(T);printf("\n");

	fclose(stdout);
	fclose(stdin);
	return 0;
}