Cod sursa(job #320480)

Utilizator DastasIonescu Vlad Dastas Data 4 iunie 2009 19:34:03
Problema Nums Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>

using namespace std;

const int maxn = 100002;
const int maxarb = 1 << 18;

ifstream in("nums.in");
ofstream out("nums.out");

struct trie
{
    int nr;

    trie *next[10];

    trie()
    {
        nr = 0;
        memset(next, 0, sizeof(next));
    }
};

struct info
{
    int nr;

    trie *T;
};

int n;
info a[maxn];
string buf;

void insert(trie *&node, const char num[], bool &ok)
{
    if ( *num == '\0' )
    {
        if ( !node->nr )
            node->nr = 1;

        return;
    }

    int val = *num - '0';

    if ( !node->next[val] )
    {
        node->next[val] = new trie;
        ok = 1;
    }

    insert(node->next[val], num + 1, ok);
    node->nr += ok;
}

void update(int nod, int st, int dr, int len)
{
    if ( len < st || len > dr || nod >= maxn )
        return;

    if ( st == dr )
    {
        bool t = 0;

        if ( !a[nod].T )
            a[nod].T = new trie;
        insert(a[nod].T, buf.c_str(), t);

        a[nod].nr = a[nod].T->nr;

        return;
    }

    int q = nod << 1;
    int m = (st + dr) >> 1;

    update(q, st, m, len);
    update(q+1, m+1, dr, len);

    if ( q < maxn )
        a[nod].nr = a[q].nr;
    if ( q + 1 < maxn )
        a[nod].nr += a[q+1].nr;
}

void print_kth(trie *&node, int poz, char cif)
{
    if ( !node )
        return;

    if ( cif != '-' )
        out << cif;

    int start = 0;

    for ( int i = 0; i < 10; ++i )
        if ( node->next[i] )
        {
            if ( node->next[i]->nr < poz )
                poz -= node->next[i]->nr;
            else
            {
                start = i;
                break;
            }
        }

    print_kth(node->next[start], poz, start + '0');
}

void query(int nod, int st, int dr, int poz)
{
    if ( nod >= maxn ) return;

    if ( st == dr )
    {
        print_kth(a[nod].T, poz, '-');

        return;
    }

    int q = nod << 1;
    int m = (st + dr) >> 1;

    if ( a[q].nr < poz )        query(q+1, m+1, dr, poz - a[q].nr);
    else                        query(q, st, m, poz);
}

int main()
{
    in >> n;

    int op, k;
    for ( int i = 1; i <= n; ++i )
    {
        in >> op;
        if ( op == 1 )
        {
            in >> buf;

            update(1, 1, maxn, buf.size());
        }
        else
        {
            in >> k;
            query(1, 1, maxn, k);
            out << '\n';
        }
    }

    return 0;
}