Cod sursa(job #2724350)

Utilizator stefan.popescuPopescu Stefan stefan.popescu Data 16 martie 2021 22:53:53
Problema Nums Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
#include <bits/stdc++.h>
using namespace std;
#define SERVER 0
const string nameFile="nums";
ifstream in (nameFile+".in");
ofstream out(nameFile+".out");
typedef pair<int, int> Pii;
#if (SERVER)
    #define in cin
    #define out cout
#endif

inline bool isSmaller(string & s1, string & s2){
    if(s1.size()==s2.size())
        return s1<s2;
    return s1.size()<s2.size();
}
inline bool isEqual(string & s1, string & s2){
    return s1==s2;
}
mt19937 rng;
struct treapNode{
    string val;
    int subSize, prior;
    treapNode * st, * dr;
    treapNode(){
        subSize=1;
        prior=uniform_int_distribution<int> (-2e9, 2e9)(rng);
        st=dr=nullptr;
    }
};
class Treap{
public:
    treapNode * root;
    Treap(){
        root=nullptr;
    }
    void insert(treapNode * & trp){
        if(findUtil(root, trp->val)==false)
            insertUtil(root, trp);
    }
    void getKth(int val){
        treapNode * nodAct=root;
        while(nodAct!=nullptr){
            if(val==getSub(nodAct->st)+1){
                out<<nodAct->val<<"\n";
                return;
            }
            else if(val<=getSub(nodAct->st))
                nodAct=nodAct->st;
            else
                val-=getSub(nodAct->st)+1, nodAct=nodAct->dr;
        }
    }
    void afis(treapNode * n1){
        if(n1==nullptr)
            return;
        afis(n1->st);
        cerr<<n1->val<<" ";
        afis(n1->dr);
    }
private:
    bool findUtil(treapNode * nn, string & val){
        while(nn!=nullptr){
            if(isEqual(nn->val, val))
                return true;
            else if(isSmaller(nn->val, val))
                nn=nn->dr;
            else
                nn=nn->st;
        }
        return false;
    }
    void insertUtil(treapNode * & nodAct, treapNode * & trp){
        if(nodAct==nullptr){
            nodAct=trp;
            return;
        }
        if(trp->prior>nodAct->prior){
            splitUtil(nodAct, trp->st, trp->dr, trp->val);
            nodAct=trp, getSub(nodAct);
            return;
        }
        if(isSmaller(nodAct->val, trp->val))
            insertUtil(nodAct->dr, trp);
        else
            insertUtil(nodAct->st, trp);
        getSub(nodAct);
    }
    inline int getSub(treapNode * ptr){
        return ptr==nullptr ? 0 : ptr->subSize;
    }
    inline void recalc(treapNode * ptr){
        if(ptr!=nullptr)
            ptr->subSize=getSub(ptr->st)+1+getSub(ptr->dr);
    }
    void splitUtil(treapNode * x, treapNode * & y, treapNode * & z, string & s){
        if(x==nullptr)
            y=z=nullptr;
        else if(isSmaller(s, x->val))
            splitUtil(x->st, y, x->st, s), z=x, recalc(z);
        else
            splitUtil(x->dr, x->dr, z, s), y=x, recalc(y);
    }
};
int qq;
int caz, val;
int main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    Treap arb;
    in>>qq;
    while(qq--){
        in>>caz;
        if(caz==1){
            treapNode * ttt=new treapNode();
            in>>ttt->val;
            arb.insert(ttt);
            //arb.afis(arb.root); cerr<<"\n";
        }
        else{
            in>>val;
            arb.getKth(val);
        }
    }
    return 0;
}