Cod sursa(job #1317502)

Utilizator Tester100Tester Tester100 Data 14 ianuarie 2015 22:31:39
Problema Nums Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <iostream>
#include <unordered_map>
#include <vector>
#include <set>
#include <string>
#include <algorithm>

using namespace std;
const int NMAX = 100002;
int op[NMAX], index[NMAX], ind[NMAX], lsb[NMAX];
string s[NMAX];
vector < int >v[NMAX];
struct cmp
{
    bool operator ()(const int i,const int j)
    {
        return s[i] < s[j];
    }
};
set < int,cmp >S[NMAX];
struct AIB{
    vector <int > aib;
    int n;
    AIB()
    {
        n = 0;
        aib.clear();
    }
    AIB(const int _n)
    {
        n = _n;
        aib.resize(n+1);
    }
    inline void Update(int pos)
    {
        for(;pos<=n;pos+=lsb[pos])
            aib[pos]++;
    }
    inline int Query(int pos)
    {
        int ret = 0;
        for(;pos>0;pos-=lsb[pos])
            ret += aib[pos];
        return ret;
    }
};
AIB V[NMAX];
int main()
{
    freopen("nums.in","r",stdin);
    freopen("nums.out","w",stdout);
    cin.sync_with_stdio(false);
    int n;
    cin >> n;
    for(int i=1;i<=100000;++i)
        lsb[i] = i & -i;
    AIB A(NMAX);
    for(int i=1;i<=n;++i)
    {
        cin >> op[i];
        if(op[i]==1){
            cin >> s[i];
            int L = s[i].length();
            if(S[L].find(i)!=S[L].end())
                continue;
            S[L].insert(i);
        }
        else
            cin >> index[i];
    }
    for(int i=1;i<=100000;++i){
        int j = 1;
        for(auto x=S[i].begin();x!=S[i].end();++x,++j){
                v[i].push_back(*x);
                ind[*x] = j;
            }
        S[i].clear();
        V[i] = AIB(j);
    }
    for(int i=1;i<=n;++i)
        if(op[i]==1){
            cin >> s[i];
            int L = s[i].length();
            if(S[L].find(i)!=S[L].end())
                continue;
            A.Update(L);
            V[L].Update(ind[i]);
        }
        else{
            int pos = index[i];
            int L = NMAX;
            int Left = 1;
            int Right = L-1,mid;
            while(Left<=Right)
            {
                mid = (Left+Right)/2;
                if(A.Query(mid) >= pos)
                {
                    L = mid;
                    Right = mid-1;
                }
                else
                    Left =  mid+1;
            }
            pos -= A.Query(L-1);

            int sol = v[L].size();
            Left = 1;
            Right = sol;
            while(Left<=Right)
            {
                mid = (Left+Right)/2;
                if(V[L].Query(mid) >= pos)
                {
                    sol = mid;
                    Right = mid-1;
                }
                else
                    Left =  mid+1;
            }
            cout<<s[v[L][sol-1]]<<"\n";
        }
    return 0;
}