Cod sursa(job #1678693)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 7 aprilie 2016 14:56:49
Problema Nums Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <fstream>
#include <cstring>
#include <string>
#include <utility>
#include <cassert>

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];
}

int query(int pos) {
    int ans = 0;
    for (; pos; pos -= lsb(pos))
        ans += aib[pos];
    return ans;
}

pair <int, int> binary_search(int 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, pos + 1);*/

    int st = 1;
    int dr = LMAX - 1;
    int mid;
    int ans;


    while (st <= dr) {
        mid = (st + dr) >> 1;
        if (query(mid) >= k) {
            dr = mid - 1;
            ans = mid;
        }
        else
            st = mid + 1;
    }

    return make_pair(k - query(ans - 1), ans);
}

struct trie {
    int sz;
    trie* alf[10];

    trie(int _sz = 0): sz(_sz) {
        memset(alf, NULL, sizeof alf);
    }
} *roots[LMAX];

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

    update(str.size());

    for (auto it: str) {
        ++ node -> sz;
        if (node -> alf[it - '0'] == NULL)
            node -> alf[it - '0'] = new trie;
        node = node -> alf[it - '0'];
    }

    //Finalul
    ++ node -> sz;
}

ofstream cout("nums.out");
void get_kth(int k) {
    string ans;

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

    trie *node = roots[aux.second];

    while (1) {
        int i;
        for (i = 0; i < 10; ++ i)
            if (node -> alf[i] != NULL) {
                if (node -> alf[i] -> sz <= k)
                    k -= node -> alf[i] -> sz;
                else {
                    ans += (char)('0' + i);
                    node = node -> alf[i];
                    break;
                }
            }

        if (i == 10)
            break;
    }

    cout << ans << '\n';
}

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

    int n = 0;
    cin >> n;

    bool type;
    string str;
    int k;
    while (n --) {
        cin >> type;
        if (!type) {
            cin >> k;
            get_kth(k);
        }
        else {
            cin >> str;
            assert(str.size() && str[0] != '0' && str.size() >= 1 && str.size() <= 100000);

            insert(str);
        }
    }

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