Cod sursa(job #571012)

Utilizator crushackPopescu Silviu crushack Data 3 aprilie 2011 21:08:53
Problema Nums Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include <stdio.h>
#include <string.h>
#define LMax 100010
#define zeros(x) ( ( x ^ (x-1)) & x )

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

struct nod{
	int nums;
	nod *next[10];
	nod(){
		nums=0;
		memset(next,0,sizeof(next));
	}
} *trie,*ad[LMax];

int N,K;
int arb[LMax];
char s[LMax];

void arbInsert(int x,int v)
{
	for (;x<LMax;x+=zeros(x))
		arb[x]+=v;
}

int arbSearch(int v)
{
	int i,step,sum=0;
	for (i=1;i<=LMax && arb[i]<v;i<<=1);
	step=i;
	sum=i;
	for (;step;step>>=1)
		if ( i-step>=sum && ( (i-step)%2!=0 && arb[i-step]+arb[i-step-1]+arb[sum]<=v || (i-step)%2==0 && arb[i-step]+arb[sum]>=v) )
			i-=step;
	return i;
}

void init(nod *trie)
{
	int i;
	ad[LMax-1]=trie=new nod;
	for (i=2;i<LMax;++i)
		ad[LMax-i]=trie=trie->next[0]=new nod;
}

void add(char *s)
{
	int L=strlen(s);
	arbInsert(L,1);
	nod *trie=ad[L];
	++trie->nums;
	while (*s!='\0')
	{
		if (!trie->next[*s-'0'])
			trie->next[*s-'0']=new nod;
		trie=trie->next[*s-'0'];
		++trie->nums;
		++s;
	}
}

bool query(char *s)
{
	int L=strlen(s);
	nod *trie=ad[L];
	while (*s!='\0')
	{
		if (!trie->next[*s-'0']) return false;
		trie=trie->next[*s-'0'];
		++s;
	}
	return true;
}

void Query(int K)
{
	int i;
	nod *trie= ad[arbSearch(K)];
	while (trie->next[0] && K<=trie->next[0]->nums)
		trie=trie->next[0];
	while (K && trie)
	{
		for (i=0;i<10;++i)
			if (trie->next[i] && K>trie->next[i]->nums)
				K-=trie->next[i]->nums;
			else if (trie->next[i])
				break;
		if (i==10) break;
		printf("%d",i);
		trie=trie->next[i];
	}
	printf("\n");
}

int main()
{
	int i,c;
	freopen(IN,"r",stdin);
	scanf("%d",&N);
	init(trie); 
	
	freopen(OUT,"w",stdout);
	for (i=0;i<N;++i)
	{
		scanf("%d",&c);
		switch(c)
		{
			case 1:
				scanf("%s",s);
				if (!query(s))
					add(s);
			break;
			case 0:
				scanf("%d",&K);
				Query(K);
			break;
		}
	}
	fclose(stdout);
	fclose(stdin);
	return 0;
}