Cod sursa(job #479927)

Utilizator Bogdan_tmmTirca Bogdan Bogdan_tmm Data 25 august 2010 17:08:45
Problema Nums Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
#define N_MAX 100002
string a[N_MAX];
char c[N_MAX];
int n,i,j,t,k,N,NN;
int aib[N_MAX],op[N_MAX];
int Lg,lg;
struct trie
{
	int cuvant;
	int prefix;
	trie *cifra[10];
	trie()
	{
		memset(cifra,0,sizeof(cifra));
		prefix=cuvant=0;
	}
};

trie *A[N_MAX],*Rad;

int Exista(string x,trie *nod)
{
	int i,n=(int)x.size(),cif;

	for(i=0;i<n;i++)
	{
		cif=x[i]-'0';
		if(nod->cifra[cif]==0)
			return 0;
		nod=nod->cifra[cif];
	}
	if(nod->cuvant)
		return 1;
	return 0;
}

void Add(int which,string x,trie *nod)
{
	int i,n=(int)x.size(),cif;

	nod->prefix++;
	for(i=0;i<n;i++)
	{
		cif=x[i]-'0';
		if(nod->cifra[cif]==0)
			nod->cifra[cif]=new trie;
		nod=nod->cifra[cif];
		nod->prefix++;
	}
	nod->cuvant=which;
}

inline int LSB(int i)
{
	return i&(-i);
}

void update(int ind,int val)
{
	for(int i=ind;i<=Lg;i+=LSB(i))
		aib[i]+=val;
}

int query(int &sum)
{
	int i,step;
	for(step=1;step<Lg;step<<=1);
	for(i=0;step;step>>=1)
		if(i+step<=Lg&&aib[i+step]<sum)
		{
			i+=step;
			sum-=aib[i];
			if(!sum)
				return i;
		}
	return i+1;
}

int query2(int sum,trie *nod)
{
	int cif,i,j;
	while(1)
	{
		i=0;
		for(cif=0;cif<=9;cif++)
		{
			if(nod->cifra[cif]==0)
				continue;
			j=i+nod->cifra[cif]->prefix;
			if(j>=sum)
				break;
			i=j;
		}
		sum-=i;
		nod=nod->cifra[cif];
		if(nod->cuvant)
			break;
	}
	return nod->cuvant;
}

int QUERY(int k)
{
	int sum=k,lg;
	lg=query(sum);

	return query2(sum,A[lg]);
}

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

	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&t);
		if(t)
		{
			scanf("%s",c);
			a[++N]=c;	
			lg=(int)a[N].size();
			Lg=max(Lg,lg);
		}
		else
		{
			scanf("%d",&k);
			op[i]=k;
		}
	}
	
	for(i=1;i<=Lg;i++)
		A[i]=new trie;

	for(i=1;i<=n;i++)
	{
		if(op[i]==0)
		{
			NN++;
			lg=(int)a[NN].size();
			if(!Exista(a[NN],A[lg]))
			{
				Add(NN,a[NN],A[lg]);
				update(lg,1);
			}
		}
		else
		{
			j=QUERY(op[i]);
			printf("%s\n",a[j].c_str());
		}
	}

	return 0;
}