Cod sursa(job #2605177)

Utilizator alextodoranTodoran Alexandru Raul alextodoran Data 24 aprilie 2020 16:21:33
Problema Nums Scor 65
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.96 kb
#include <bits/stdc++.h>

using namespace std;

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

const int N_MAX = 100002;
const int L_MAX = 100002;

int n;

struct TrieNode
{
    vector <pair <int, TrieNode*> > sons;
    int index;
    int subSize;
    TrieNode ()
    {
        sons.clear();
        this->index = 0;
        this->subSize = 0;
    }
};

TrieNode* roots[L_MAX];

bool TrieInsert (TrieNode* node, char* str, int index)
{
    if(str[0] == '\0')
    {
        if(node->index == 0)
        {
            node->index = index;
            node->subSize++;
            return true;
        }
        return false;
    }
    for(int i = 0; i < node->sons.size(); i++)
        if(node->sons[i].first == str[0] - '0')
        {
            if(TrieInsert(node->sons[i].second, str + 1, index) == true)
            {
                node->subSize++;
                return true;
            }
            return false;
        }
    node->sons.push_back(make_pair(str[0] - '0', new TrieNode()));
    int pos = (int)node->sons.size() - 1;
    while(pos > 0 && node->sons[pos].first < node->sons[pos - 1].first)
    {
        swap(node->sons[pos], node->sons[pos - 1]);
        pos--;
    }
    if(TrieInsert(node->sons[pos].second, str + 1, index) == true)
    {
        node->subSize++;
        return true;
    }
    return false;
}

string ans;

void TrieFind (TrieNode* node, int k)
{
    if(k == 1 && node->index != 0)
        return;
    for(int i = 0; i < node->sons.size(); i++)
    {
        if(k <= node->sons[i].second->subSize)
        {
            ans += char(node->sons[i].first + '0');
            TrieFind(node->sons[i].second, k);
            return;
        }
        k -= node->sons[i].second->subSize;
    }
}

int BIT[L_MAX];

void BITupdate (int pos)
{
    for(int i = pos; i <= 100000; i += i & -i)
        BIT[i]++;
}

int BITquery (int pos)
{
    int ans = 0;
    for(int i = pos; i >= 1; i -= i & -i)
        ans += BIT[i];
    return ans;
}

int BITqueryCnt (int cnt)
{
    int ans = 0;
    for(int step = 16; step >= 0; step--)
        if(ans + (1 << step) <= 100000 && BIT[ans + (1 << step)] < cnt)
        {
            ans += (1 << step);
            cnt -= BIT[ans];
        }
    ans++;
    return ans;
}

char aux[L_MAX];

int main()
{
    fin >> n;
    for(int i = 1; i <= n; i++)
    {
        bool op;
        fin >> op;
        if(op == 0)
        {
            int k;
            fin >> k;
            int rootIndex = BITqueryCnt(k);
            ans = "";
            TrieFind(roots[rootIndex], k - BITquery(rootIndex - 1));
            fout << ans << "\n";
        }
        else
        {
            fin >> aux;
            int lg = strlen(aux);
            if(roots[lg] == nullptr)
                roots[lg] = new TrieNode();
            if(TrieInsert(roots[lg], aux, i))
                BITupdate(lg);
        }
    }
    return 0;
}