Cod sursa(job #1669959)

Utilizator ZenusTudor Costin Razvan Zenus Data 31 martie 2016 12:09:46
Problema Nums Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <bits/stdc++.h>

using namespace std;

const int nmax = 100009;
const int cmax = 100000;

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

struct trie
{
    int cnt;
    trie *link[10];

    trie()
    {
        cnt = 0;
        for (int i = 0 ; i <= 9 ; ++i)
        link[i] = 0;
    }
};

int st[4 * nmax];
trie *root[nmax];
int n , m , k , i , t;
string act;

void add(int x , int l , int r , int p)
{
    if (l == r)
    {
        st[x]++;
        return ;
    }

    int c = (l + r) / 2;
    if (p <= c) add(2 * x , l , c , p);
    else add(2 * x + 1 , c + 1 , r , p);

    st[x] = st[2 * x] + st[2 * x + 1];
}

int query(int x , int l , int r)
{
    if (l == r) return r;

    int c = (l + r) / 2;
    if (k <= st[2 * x]) query(2 * x , l , c);
    else
    {
        k -= st[2 * x];
        query(2 * x + 1 , c + 1 , r);
    }
}

bool runSearch(trie *root , int p)
{
    if (p == n) return true;

    int to = act[p] - '0';
    if (root -> link[to]) runSearch(root -> link[to] , p + 1);
    else return false;
}

bool runSearch(trie *root)
{
    int to , p = 0;
    while (p < n)
    {
        to = act[p] - '0';
        p++;

        if (root -> link[to])
        {
            root = root -> link[to];
            continue;
        }
        return false;
    }
    return true;
}

void runInsert(trie *root)
{
    int p = 0 , to;

    while (p < n)
    {
        root -> cnt++;
        to = act[p] - '0';
        p++;

        if (root -> link[to]);
        else root -> link[to] = new trie();

        root = root -> link[to];
    }
    root -> cnt++;
}

void runWrite(trie *root)
{
    int p = 0 , to;

    while (p < n)
    {
        p++;

        for (i = 0 ; i <= 9 ; ++i)
        if (root -> link[i])
        {
            if (root -> link[i] -> cnt >= k)
            {
                act.push_back(i + '0');
                root = root -> link[i];
                break;
            }
            else k -= root -> link[i] -> cnt;
        }
    }
}

int main()
{

for (fin >> m ; m ; --m)
{
    fin >> t;

    if (t == 1)
    {
        fin >> act;
        n = act.size();

        if (root[n]);
        else root[n] = new trie();

        if (runSearch(root[n])) ;
        else
        {
            runInsert(root[n]);
            add(1 , 1 , cmax , n);
        }
    }
    else
    {
        fin >> k;
        n = query(1 , 1 , cmax);

        act.clear();
        runWrite(root[n]);
        fout << act << "\n";
    }
}

return 0;
}