Cod sursa(job #574854)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 7 aprilie 2011 17:03:25
Problema Order Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.23 kb
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define Nmax 30010

int n,i,p;

struct Treap 
{
	int key,priority,heavy;
	Treap *left,*right;
	
	Treap() {} 
	Treap( int key, int priority, Treap *left, Treap *right )
	{
		this->key      = key      ; 
		this->priority = priority ;
		this->heavy    = 0        ; 
		this->left     = left     ;
		this->right    = right    ;
	}
} *R, *NIL ;


void init()
{
	srand(time(0));
	R = NIL = new Treap(0,0,NULL,NULL);
}

void rotleft( Treap *&nod )
{
	Treap *t = nod->left ;
	nod->heavy -= (t->heavy+1);
	
	nod->left = t->right , t->right = nod ;
	nod = t ;
}

void rotright( Treap *&nod )
{
	Treap *t = nod->right;
	t->heavy += (nod->heavy+1);
	
	nod->right = t->left , t->left = nod ;
	nod = t ;
}

void balance( Treap *&nod )
{
	if( nod->left->priority > nod->priority )
		rotleft(nod);
	else
		if( nod->right->priority > nod->priority )
			rotright(nod);
}

void insert( Treap *&nod, int key, int priority )
{
	if( nod == NIL )
	{
		nod = new Treap(key,priority,NIL,NIL);
		return ; 
	}
	
	if( key < nod->key ) 
		insert(nod->left,key,priority);
	else
		insert(nod->right,key,priority);
	
	balance(nod);
}

void erase( Treap *&nod, int key )
{
	if( nod == NIL ) return ;
	
	if( key < nod->key ) 
	{
		nod->heavy--;
		erase(nod->left,key);
	}
	else if( key > nod->key )
		erase(nod->right,key);
	else 
	{
		if( nod->left == NIL && nod->right == NIL ) 
			delete nod, nod = NIL ; 
		else
		{
			if( nod->left->priority > nod->right->priority )
				rotleft(nod);
			else 
				rotright(nod);
			erase(nod,key);
		}
	}
}

void find_and_erase( Treap *&nod, int poz )
{
	if( poz == nod->heavy + 1 ) 
	{
		printf("%d ",nod->key);
		erase(nod,nod->key);
		return ;
	}
	
	if( poz < nod->heavy + 1 ) 
	{
		nod->heavy--;
		find_and_erase(nod->left,poz);
	}
	else
		find_and_erase(nod->right,poz-nod->heavy-1);
}

int main()
{
	freopen("order.in","r",stdin);
	freopen("order.out","w",stdout);
	
	scanf("%d",&n);
	
	init();
	for( i = 1 ; i <= n ; i++ )
		insert(R,i,rand()+1);
	
	for( p = 1 , i = 1 ; n ; n-- , i++ , p-- ) 
	{
		p = ( p + i ) % n ; if(!p) p = n ;
		find_and_erase(R,p);
	}
	
	return 0 ; 
}