Cod sursa(job #809720)

Utilizator dicu_dariaDaria Dicu dicu_daria Data 8 noiembrie 2012 22:02:36
Problema Nums Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.58 kb
#include <fstream>
#include <cstring>
#define L 100000
using namespace std;
int arb[700010], m, n, k, t, q, p, i;
bool undo = 1;
string s;
struct Trie
{
    Trie *fiu[10];
    int cnt;
    Trie()
    {
        cnt = 0;
        memset(fiu, 0, sizeof(fiu));
    }
};
void add(int nod, int l, int r)
{
    arb[nod]++;
    if(l == r) return;
    m = (l+r)/2;
    if(n <= m)
    {
        add(nod*2, l, m);
        arb[nod*2+1]++;
    }
    else add(nod*2+1, m+1, r);

}
void search(int nod, int l, int r)
{
    if(l == r)
    {
        n = l;
        return;
    }
    m = (l+r)/2;
    if(arb[2*nod] >= k) search(nod*2, l, m);
    else
    {
        k -= arb[nod*2];
        search(nod*2+1, m+1, r);
    }
}
Trie *T[100010];
Trie *nod = new Trie;
int main()
{
    ifstream fi("nums.in");
    ofstream fo("nums.out");
    fi >> q;
    for(i = 1; i <= L; i++) T[i] = new Trie;
    while(q--)
    {
        fi >> t;
        if(t == 0)
        {
            fi >> k;
            //caut lungimea de trie = n
            s = "";
            search(1, 1, L);
            nod = T[n];
            p = 0;
            while(1)
            {
                if(p >= n) break;
                for(i = 0; i <= 9; i++)
                    if(nod->fiu[i] and nod->fiu[i]->cnt < k)
                    {
                        k -= nod->fiu[i]->cnt;
                        continue;
                    }
                    else if(nod->fiu[i])
                    {
                        nod = nod->fiu[i];
                        s += i+'0';
                        p++;
                        break;
                    }
            }
            fo << s << "\n";
        }
        else
        {
            fi >> s;
            n = s.size();
            //verific daca il am la colectie

            //adaug in arborele de intervale;
            nod = T[n];
            p = 0; undo = 0;
            while(1)
            {
                if(p != 0) nod->cnt++;
                if(p == n and nod->cnt > 1) undo = 1;
                if(p >= n) break;
                if(!nod->fiu[s[p]-'0'])
                {
                    nod->fiu[s[p]-'0'] = new Trie;
                }
                nod = nod->fiu[s[p]-'0'];
                p++;
            }
            if(undo == 1)
            {
                nod = T[n];
                p = 0; undo = 0;
                while(1)
                {
                    if(p != 0) nod->cnt--;
                    if(p >= n) break;
                    nod = nod->fiu[s[p]-'0'];
                    p++;
                }
            }
            add(1, 1, L);
        }
    }
    return 0;
}