Cod sursa(job #865003)

Utilizator vendettaSalajan Razvan vendetta Data 25 ianuarie 2013 22:19:13
Problema Nums Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>

using namespace std;

ifstream f("nums.in");
ofstream g("nums.out");

#define nmax 100005

#define ll long long

struct Query{
    int ord;
    bool tip;
    string S;
};
struct Aint{
    int val,poz;
};

Aint aint[nmax*4];
Query q[nmax];
bool viz[nmax];
pair<string, int> V[nmax];
int Ord = 0, Tot, n, sz;
string S;

void citeste(){
    f >> n;
    int tip;
    for(int i=1; i<=n; ++i){
        S.clear();
        f >> tip; f >> S;
        q[i].tip = tip; q[i].S = S;
        if (tip == 1) ++sz, V[sz] = make_pair(S, i);
    }
}

void update(int nod, int st, int dr, int poz, int val, int ceva){
    if (st == dr){
        aint[nod].val = 1; aint[nod].poz = ceva;// pozitia in vectorul initial ca sa pot raspunde ca imi trebuie tot numarul
        return;
    }else {
        int mij = (st + dr) / 2;
        if (poz <= mij) update(nod*2, st, mij, poz, val, ceva);
                   else update(nod*2+1, mij+1, dr, poz, val, ceva);
        aint[nod].val = aint[nod*2].val + aint[nod*2+1].val;
    }
}

void afla(int nod, int st, int dr, int k, int &poz){
    if (st == dr){
        poz = aint[nod].poz;
        return;
    }else {
        int mij = (st + dr) / 2;
        if (k <= aint[nod*2].val){// se afla pe intervalul st, mij
            afla(nod*2, st, mij, k, poz);
        }else afla(nod*2+1, mij+1, dr, k - aint[nod*2].val, poz);
    }
}

inline bool cmp( pair<string, int> A, pair<string, int> B){
    if (A.first.size() == B.first.size()){
        int i  =0;
        for(; i<A.first.size(); ++i){
            if (A.first[i] != B.first[i]) break;
        }
        if (i < A.first.size()){
            return A.first[i] < B.first[i];
        }else return 1;
    }else return A.first.size() < B.first.size();
}

void rezolva(){
    // ideea ar fi asa : daca numerele ar intra pe ll atunci as baga o preprocesare in care le-as sorta si i-as atrbui fiecarei din cele Nmax
    //valori pozitie in vectorul sortat iar apoi pornesc de la inceput si bag intr-un aint numelere si la un queury vad cate numere sunt in fata mea
    // daca numerele astea sunt gigant atunci le sortez si pe astea doar ca le citesc initial ca si string si in rest fac la fel
    sort(V+1, V+sz+1, cmp);
    int ceva = 1; q[ V[1].second ].ord = ceva;
    for(int i=2; i<=sz; ++i){
        //cout << V[i].first << "\n";
        if (V[i].first == V[i-1].first){
            q[ V[i].second ].ord = ceva;
        }else {
            ++ceva;
            q[ V[i].second ].ord = ceva;
        }
    }
    //acum stiu pentru fiecare numar din fisierul de intrare pe ce pozitie se afla in vectorul sortat
    for(int i=1; i<=n; ++i){
        if (q[i].tip == 0){// e query
            int k = 0; S = q[i].S;
            for (int i=0; i<S.size(); ++i)
                k = k * 10 + (S[i]-'0');
            // a k-a pozitie
            int poz = 0; afla(1, 1, n, k, poz);
            g << q[poz].S << "\n";
        }else {// e update
            //cout << q[i].ord << "\n";
            if (viz[ q[i].ord ] == 1) continue;//daca am mai baga numarul
            viz[ q[i].ord ] = 1;
            update(1, 1, n, q[i].ord, 1, i);// bag numarul
        }
    }
}

int main(){
    citeste();
    rezolva();

    f.close();
    g.close();

    return 0;
}