Cod sursa(job #2605161)

Utilizator alextodoranTodoran Alexandru Raul alextodoran Data 24 aprilie 2020 15:59:01
Problema Nums Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.48 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
{
    TrieNode* sons[10];
    int index;
    int subSize;
    TrieNode ()
    {
        for(int i = 0; i <= 9; i++)
            this->sons[i] = nullptr;
        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;
    }
    if(node->sons[str[0] - '0'] == nullptr)
        node->sons[str[0] - '0'] = new TrieNode();
    if(TrieInsert(node->sons[str[0] - '0'], str + 1, index) == true)
    {
        node->subSize++;
        return true;
    }
    return false;
}

void TrieFind (TrieNode* node, int k)
{
    if(k == 1 && node->index != 0)
        return;
    for(int i = 0; i <= 9; i++)
        if(node->sons[i] != nullptr)
        {
            if(k <= node->sons[i]->subSize)
            {
                fout << i;
                TrieFind(node->sons[i], k);
                return;
            }
            k -= node->sons[i]->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 <= 100000; i++)
        roots[i] = new TrieNode();
    for(int i = 1; i <= n; i++)
    {
        bool op;
        fin >> op;
        if(op == 0)
        {
            int k;
            fin >> k;
            int rootIndex = BITqueryCnt(k);
            TrieFind(roots[rootIndex], k - BITquery(rootIndex - 1));
            fout << "\n";
        }
        else
        {
            fin >> aux;
            int lg = strlen(aux);
            if(TrieInsert(roots[lg], aux, i))
                BITupdate(lg);
        }
    }
    return 0;
}