Pagini recente » Cod sursa (job #756803) | Cod sursa (job #1352733) | Cod sursa (job #1337819) | Cod sursa (job #2866459) | Cod sursa (job #640038)
Cod sursa(job #640038)
#include <fstream>
#include <cstring>
#include <string>
using namespace std;
#define DIM 8+(1<<18)
#define in "nums.in"
#define out "nums.out"
#define LMAX 100010
typedef struct Trie{
unsigned short cnt;
char cif;
Trie *sons,*next;
Trie(char cifra)
{
next = NULL;
sons = NULL;
cif = cifra;
cnt = 0;
}
};
Trie *numbers[LMAX];
int arb[LMAX],value;
int maxL,M,solCount = - 1,lungime;
char curent[LMAX],bytes[LMAX],sol[LMAX];
Trie* fii[10];
Trie *findAux,*pushAux,*existsAux,*insertAux,*queryAux;
ifstream fin(in);
ofstream fout(out);
//
//aib procedures
//
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;
}
//
//end of aib procedures
//
//
//trie procedures
//
inline void push(char cif,Trie* node)
{
pushAux = new Trie(cif);
pushAux->next = node->sons;
node->sons = pushAux;
}
inline Trie* find(char cif,Trie *node)
{
findAux = node->sons;
while(findAux)
{
if(findAux->cif == cif)
return findAux;
findAux = findAux->next;
}
return NULL;
}
void insert(Trie *node,char *s)
{
while(*s >= '0' && *s <= '9')
{
node->cnt++;
insertAux = find(*s,node);
if(insertAux)
s = s+1 , node = insertAux;
else
{
push(*s,node);
s = s+1;
node = node->sons;
}
}
node->cnt++;
}
bool exista(Trie *node,char *s)
{
while(*s >= '0' && *s <= '9')
{
existsAux = find(*s,node);
if(existsAux)
{
node = existsAux;
s++;
}
else
return 0;
}
return 1;
}
inline void TrieQuery(Trie *node,int position)
{
int i;
while(solCount < lungime-1)
{
for(i=0; i<10; i++)
fii[i] = NULL;
queryAux = node->sons;
while(queryAux)
{
fii[queryAux->cif-'0'] = queryAux;
queryAux = queryAux->next;
}
for(i=0; i<10; i++)
if(fii[i])
if(fii[i]->cnt < position)
position -= fii[i]->cnt;
else
{
sol[++solCount] = i + '0';
node = fii[i];
break;
}
}
}
//
//end of trie procedures
//
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 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);
sol[++solCount] = '\0';
fout<<sol<<'\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(0);
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;
}