Cod sursa(job #652650)

Utilizator indestructiblecont de teste indestructible Data 25 decembrie 2011 17:27:42
Problema Nums Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.04 kb
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
#define NMAX 100005
#define LMAX (1<<18)
#define HMAX 10
#define pb push_back
#define pii pair <int,int>
#define mp make_pair
#define f first
#define s second
using namespace std;
int t,op,ord[NMAX],C[NMAX],D[LMAX],r,poz,val[NMAX],F[NMAX],L[LMAX],R[LMAX],M[LMAX];
int st,dr,ok,dist;
char line[NMAX],ap[NMAX],pur[NMAX];
vector <char> A[NMAX];
pii B[NMAX];
struct trie
{
	int pass;
	trie *fiu[HMAX];
	trie()
	{
		pass=0;
		memset(fiu,0,sizeof(fiu));
	}
};
trie *T=new trie;
bool comp(int x,int y)
{
	return A[x].size()<A[y].size();
}
void update()
{
	poz=F[poz];
	for ( ; poz; poz>>=1)
		D[poz]++;
}
void cauta(int st,int dr,int nod)
{
	if (st==dr)
	{
		int i;
		for (i=0; i<A[val[st]].size(); i++)
			printf("%c",A[val[st]][i]);
		printf("\n");
		return ;
	}
	int mij=M[nod];
	if (D[L[nod]]<poz)
	{
		poz-=D[L[nod]];
		cauta(mij+1,dr,R[nod]);
	}
	else
		cauta(st,mij,L[nod]);
}
inline int cif(char x)
{
	return x>='0' && x<='9';
}
void cstr(int st,int dr,int nod)
{
	if (st==dr)
	{
		F[st]=nod;
		return ;
	}
	int mij=(st+dr)>>1;
	M[nod]=mij; L[nod]=nod<<1; R[nod]=L[nod]+1;
	cstr(st,mij,L[nod]);
	cstr(mij+1,dr,R[nod]);
}
void ins(trie *nod,int poz,int nr)
{
	nod->pass++;
	if (nr==A[poz].size())
	{
		if (nod->pass==2)
			ok=0,nod->pass--;
		else
			dist++;
		return ;
	}
	if (nod->fiu[A[poz][nr]-'0']==0)
		nod->fiu[A[poz][nr]-'0']=new trie;
	ins(nod->fiu[A[poz][nr]-'0'],poz,nr+1);
	if (!ok)
		nod->pass--;
}
void search(trie *nod,int poz,int nr)
{
	if (nr==A[poz].size())
		return ;
	int i;
	for (i=0; i<A[poz][nr]-'0'; i++)
		if (nod->fiu[i]!=0)
			C[poz]+=(nod->fiu[i])->pass;
	search(nod->fiu[A[poz][nr]-'0'],poz,nr+1);
}
int erase(trie *nod,int poz,int nr)
{
	nod->pass--;
	if (nr==A[poz].size())
		;
	else
		if (erase(nod->fiu[A[poz][nr]-'0'],poz,nr+1))
			nod->fiu[A[poz][nr]-'0']=0;
	if (nod->pass==0 && nod!=T)
	{
		delete nod;
		return 1;
	}
	return 0;
}
int main()
{
	freopen("nums.in","r",stdin);
	freopen("nums.out","w",stdout);
	scanf("%d\n",&t);
	int i,j,tip;
	for (i=1; i<=t; i++)
	{
		scanf("%d",&tip);
		if (tip==1)
		{
			fgets(line+1,NMAX,stdin);
			poz=0; op++;
			while (!cif(line[poz+1])) poz++;
			while (cif(line[poz+1])){ poz++; A[op].pb(line[poz]);}
			ord[op]=op;
			B[i]=mp(tip,op);
		}
		else
		{
			scanf("%d",&poz);
			B[i]=mp(tip,poz);
		}
	}
	sort(ord+1,ord+op+1,comp);
	for (i=1; i<=op; i++)
	{
		if (ap[i])
			continue ;
		st=dr=i;
		while (dr+1<=op && A[ord[dr+1]].size()==A[ord[st]].size()) dr++;
		dist=0;
		for (j=st; j<=dr; j++)
		{
			ok=1;
			ins(T,ord[j],0);
			ap[j]=1;
			if (!ok)
				pur[j]=1;
		}
		for (j=st; j<=dr; j++)
		{
			C[ord[j]]=r+1;
			search(T,ord[j],0);
			val[C[ord[j]]]=ord[j];
		}
		for (j=st; j<=dr; j++)
			if (!pur[j])
				erase(T,ord[j],0);
		r+=dist;
	}
	cstr(1,r,1);
	memset(ap,0,sizeof(ap));
		
	for (i=1; i<=t; i++)
	{
		tip=B[i].f; poz=B[i].s;
		if (tip==1)
		{
			poz=C[poz];
			if (!ap[poz])
			{
				ap[poz]=1;
				update();
			}
		}
		else
			cauta(1,r,1);
	}
	return 0;
}