Cod sursa(job #631037)

Utilizator darkseekerBoaca Cosmin darkseeker Data 6 noiembrie 2011 20:36:42
Problema Nums Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.83 kb
#include <fstream>
#include <cstring>

using namespace std;

#define DIM 8+(1<<18)
#define in "nums.in"
#define out "nums.out"
#define LMAX 100010

struct Trie{
	Trie *fii[10];
	int cnt;
	
	Trie()
	{
		for(int i = 0; i < 10; i++)
			fii[i] = NULL;
		cnt = 0;
	}
};

Trie *numbers[LMAX];
int arb[LMAX],value;
int maxL,M,solCount = - 1,lungime;
char sol[LMAX],curent[LMAX],bytes[LMAX];

ifstream fin(in);
ofstream fout(out);


inline void update(int position)
{
	while(position < LMAX)
	{
		arb[position]++;
		position += (1<<bytes[position]);
	}
}

inline int query(int position)
{
	int ans = 0;
	while(position > 0)
	{
		ans += arb[position];
		position -= (1<<bytes[position]);
	}
	return ans;
}

inline int bsearch(int value)
{
	int left,right,center,sum;
	left = 1;
	right = LMAX;
	
	while(left <= right)
	{
		center = (left + right)>>1;
		sum = query(center);
		if(sum < value)
			left = center + 1;
		else
			right = center - 1;
	}
	
	center = (left + right)/2;
	sum = query(center);
	if(sum > value)
		center--;
	return center;
}

void insert(Trie *node,char *s)
{
	node->cnt++;
	if(*s >= '0' && *s <= '9')
		if(node->fii[*s-'0'])
			insert(node->fii[*s-'0'],s+1);
		else
			{
				node->fii[*s-'0'] = new Trie();
				insert(node->fii[*s-'0'],s+1);
			}
}

bool exista(Trie *node,char *s)
{
	if(*s < '0' || *s >'9')
		return 1;
	else
	{
		if(*s >= '0' && *s <= '9')
			if(node->fii[*s-'0'])
				return 0 + exista(node->fii[*s-'0'],s+1);
			else
				return 0;
	}
}

inline int stringToNumber(char *S)
{
	int lg = strlen(S), i = 0,ans = 0;
	for(i = 0; i < lg; i++)
		ans = ans * 10 + S[i] - '0';
	return ans;
}

inline void TrieQuery(Trie *node,int position)
{
	int i;
	if(solCount < lungime-1)
		for(i = 0; i < 10; i++)
			if(node->fii[i])
				if(node->fii[i]->cnt < position)
					position -= node->fii[i]->cnt;
				else
				{
					sol[++solCount] = i + '0';
					TrieQuery(node->fii[i],position);
					break;
				}
}

inline void solve1()
{
	int lg = strlen(curent);
	lg-=2;
	if(!exista(numbers[lg],curent+2))
		{
			update(lg);
			insert(numbers[lg],curent+2);
		}
}

inline void solve2(int key)
{
	
	int poz = bsearch(key);
	if(poz != 0)
		key -= query(poz);
	solCount = -1;
	lungime = poz+1;
	TrieQuery(numbers[poz+1],key);
	for(poz = 0; poz<=solCount; poz++)
		fout<<sol[poz];
	fout<<'\n';
}

void compute()
{
	int i;
	bytes[1] = 0;
	for(i = 2; i < LMAX; i++)
		if(i % 2 == 0)
			bytes[i] = 1 + bytes[i>>1];
		else
			bytes[i] = 0;
}



int main()
{
	int N,i;
	
	compute();
	
	fin>>N;
	fin.get();
	
	char *s = NULL;
	
	for(i=1; i<LMAX; i++)
		numbers[i] = new Trie();
	
	for(i=1; i<=N; i++)
	{
		strcpy(curent," ");
		fin.get(curent,LMAX,'\n');
		fin.get();
		switch(curent[0])
		{
			case '1': solve1(); break;
			case '0': solve2(stringToNumber(curent+2));break;
		}
	}
	
	fin.close();
	fout.close();
	
	return 0;
	
}