Cod sursa(job #1678900)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 7 aprilie 2016 16:16:54
Problema Nums Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <string>
#include <utility>
#include <list>

using namespace std;

const int LMAX = 100005;
int aib[LMAX];

#define lsb(x) ((x) & (-(x)))
void update(int pos) {
    for (; pos < LMAX; pos += lsb(pos))
        ++ aib[pos];
}

pair <int, int> binary_search(int k) {
    -- k;
    int pos = 0;

    for (int i = 16; i >= 0; -- i)
        if (pos + (1 << i) < LMAX && aib[pos + (1 << i)] <= k) {
            pos += (1 << i);
            k -= aib[pos];
        }

    return make_pair(k + 1, pos + 1);
}

struct trie {
    int sz;
    char lit;
    list <trie*> alf;

    trie* get_son(char _lit) {
        for (auto it: alf)
            if (it -> lit == _lit)
                return it;
        return NULL;
    }

    trie* add_son(char _lit) {
        alf.push_front(new trie(0, _lit));

        list <trie*> :: iterator it, it2;

        for (it = alf.begin(); it != alf.end(); ++ it) {
            it2 = ++ it;
            -- it;

            if (it2 == alf.end())
                return *it;
            if ((**it).lit > (**it2).lit)
                swap(*it, *it2);
            else
                return *it;
        }
    }

    trie(int _sz = 0, char _lit = 0): sz(_sz), lit(_lit) {}
} *roots[LMAX];

bool exists(const string &str) {
    if (roots[str.size()] == NULL)
        return false;
    trie *node = roots[str.size()];

    for (auto it: str) {
        node = node -> get_son(it);
        if (node == NULL)
            return false;
    }

    return true;
}

void insert(const string &str) {
    if (roots[str.size()] == NULL)
        roots[str.size()] = new trie;
    trie *node = roots[str.size()];

    if (exists(str))
        return ;

    update(str.size());

    for (auto it: str) {
        ++ node -> sz;

        trie *aux = node -> get_son(it);
        if (aux == NULL)
            node = node -> add_son(it);
        else
            node = aux;
    }

    //Finalul
    ++ node -> sz;
}

string get_kth(int k) {
    string ans;

    pair <int, int> aux = binary_search(k);
    k = aux.first;

    trie *node = roots[aux.second];

    while (1) {
        bool out = true;
        for (auto it: node -> alf)
            if (it -> sz < k)
                k -= it -> sz;
            else {
                ans += it -> lit;
                node = it;
                out = false;
                break;
            }

        if (out == true)
            break;
    }

    return ans;
}

int main()
{
    ifstream cin("nums.in");
    ofstream cout("nums.out");

    int n = 0;
    cin >> n;

    bool type;
    string str;
    int k;
    while (n --) {
        cin >> type;
        if (!type) {
            cin >> k;
            cout << get_kth(k) << '\n';
        }
        else {
            cin >> str;
            insert(str);
        }
    }

    cin.close();
    cout.close();
    return 0;
}