Cod sursa(job #455525)

Utilizator bixcabc abc bixc Data 13 mai 2010 21:23:01
Problema Nums Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <cstdio>
#include <algorithm>
using namespace std;

#define Nmax 100002
#define Pmax 32000000

struct Treap {
	
	int key, priority, nr, nr_tot;
	Treap *left, *right;
	
	Treap (int key, int priority, int nr, int nr_tot, Treap *left, Treap *right) {
		this->key = key;
		this->nr_tot = nr_tot;
		this->priority = priority;
		this->nr = nr;
		this->left = left;
		this->right = right;
	}
} *Tr, *nil;

struct Trie {
	
	int nr;bool cuv;
	Trie *fiu[10];
	
	Trie () {
		this->nr = 0;
		this->cuv = 0;
		memset (this->fiu, 0, sizeof (this->fiu));
	}
	
} *R[Nmax];

int k, n, p, i;
char cuv[Nmax];

void rot_left (Treap* &nod) {
	
	Treap *fiu = nod->left;
	nod->left = fiu->right; fiu->right = nod;
	nod = fiu;
	nod->nr_tot = nod->left->nr_tot + nod->right->nr_tot + nod->nr;
} 

void rot_right (Treap* &nod) {
	
	Treap *fiu = nod->right;
	nod->right = fiu->left; fiu->left = nod;
	nod = fiu;
	nod->nr_tot = nod->left->nr_tot + nod->right->nr_tot + nod->nr;
}

void balance (Treap* &nod) {
	if (nod->left->priority > nod->priority)
		rot_left (nod);
	
	if (nod->right->priority > nod->priority)
		rot_right (nod);
}

void add_treap (Treap* &nod, int key, int priority) {
	
	if (nod->key == key) {
		nod->nr++; 
		nod->nr_tot = nod->left->nr_tot + nod->right->nr_tot + nod->nr;
		return ;
	}
	
	if (nod == nil) {
		nod = new Treap (key, priority, 1, 1, nil, nil);
		return ;
	}
	
	if (key < nod->key ) add_treap (nod->left, key, priority);
	else add_treap (nod->right, key, priority);
	
	balance (nod);
	nod->nr_tot = nod->left->nr_tot + nod->right->nr_tot + nod->nr;
}

int add_trie (Trie *nod, char *cuv) {
	
	if (*cuv == '\n') {
		if (!nod->cuv) {
			nod->nr++;
			nod->cuv = 1;
			return 1;
		}
		return 0;
	}
	
	if (nod->fiu[*cuv - '0'] == 0)
		nod->fiu[*cuv - '0'] = new Trie ();
	
	if (add_trie (nod->fiu[*cuv - '0'], cuv + 1)) {
		nod->nr++;
		return 1;
	}
	return 0;
}

int cauta_treap (Treap* &nod) {
	
	if (k > nod->left->nr_tot && k <= nod->left->nr_tot + nod->nr) {
		k-= nod->left->nr_tot;
		return nod->key;
	}
	
	if (k <= nod->left->nr_tot) 
		return cauta_treap (nod->left);
	else {
		k-= nod->left->nr_tot + nod->nr;
		return cauta_treap (nod->right);
	}
} 

void cauta_trie (Trie *nod) {
	
	if (p == n) return ;
	
	for (i = 0; i < 10; i++) 
		if (nod->fiu[i] != 0) {
			if (k <= nod->fiu[i]->nr) {
				printf ("%c", (char)i + '0');
				p++;
				cauta_trie (nod->fiu[i]);
				return ;
			}
			else 
				k-= nod->fiu[i]->nr;
		}
}

int main () {
	
	freopen ("nums.in", "r", stdin);
	freopen ("nums.out", "w", stdout);

	Tr = nil = new Treap (0, 0, 0, 0, NULL, NULL);
	for (int i = 1; i <= 100000; i++)
		R[i] = new Trie ();
	
	int T, tip;
	for (scanf ("%d", &T); T; T--) {
		scanf ("%d ", &tip);
		if (tip == 1) {
			scanf ("%s", cuv);
			n = strlen (cuv); cuv[n] = '\n';
			if (add_trie (R[n], cuv)) {
				add_treap (Tr, n, rand() % Pmax + 1);
			}
		}
		
		else {
			scanf ("%d", &k);
			n = cauta_treap (Tr);
			p = 0;
			cauta_trie (R[n]);
			printf ("\n");
		}
	}
	
	return 0;
}