Cod sursa(job #317074)

Utilizator Pepelea_FlaviuFlaviu Pepelea Pepelea_Flaviu Data 22 mai 2009 15:19:44
Problema Nums Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.26 kb
# include <cstdio>
# include <string>
//# include <time.h>

using namespace std;

# define FIN "nums.in"
# define FOUT "nums.out"
# define MAXN 100005
# define MAXM 1 << 18
# define MAXL 100000
# define Sigma 10

struct Trie
{
       int Cnt, OK;
       Trie *Fiu[Sigma];

       Trie()
       {
           Cnt = OK = 0;

           memset(Fiu, 0, sizeof(Fiu));
       }
} *Num[MAXN];

int T[MAXN];
char s[MAXN];
char R[MAXN];
int Arb[MAXM];
int N, M, i, j, L, ct, cc, li;

    void Update(int Nod, int St, int Dr, int Value)
    {
        ++Arb[Nod];

        if (St == Dr) return;

        int Mij = (St + Dr) >> 1;

        if (Value <= Mij) Update(Nod << 1, St, Mij, Value);
        else Update(Nod << 1 | 1, Mij + 1, Dr, Value);
    }

    void Add( Trie *Numar, int ind)
    {   
        int i;
        Trie *p;

        p = Numar;
        for (i = 3; i <= L; ++i)
        {
            if (p -> Fiu[s[i] - '0'] == NULL) p -> Fiu[s[i] - '0'] = new Trie;

            p = p -> Fiu[s[i] - '0'];
        }

        if (!p -> OK)
        {
            p -> OK = 1;

            p = Numar;
            for (i = 3; i < L; ++i)
            {
                p = p -> Fiu[s[i] - '0'];
                ++p -> Cnt;
            }
        }
    }

    void Init()
    {
        for (i = 0; i <= MAXL; ++i) Num[i] = new Trie;
    }

    void Query(int Nod, int St, int Dr, int Value)
    {
        if (St == Dr)
        {
            L = St;

            return;
        }

        int Mij = (St + Dr) >> 1;

        if (Arb[Nod << 1] < Value)
        {
            M -= Arb[Nod << 1];
            Query(Nod << 1 | 1, Mij + 1, Dr, Value - Arb[Nod << 1]);
        } else Query(Nod << 1, St, Mij, Value);
    }

    void Print(int P, int M, Trie *Numar)
    {
        int i, j;

        for (i = 1; i < P; ++i)
        {
            for (j = 0; j <= 9; ++j)
            {
                if (Numar -> Fiu[j] != NULL)
                  if (Numar -> Fiu[j] -> Cnt >= M) 
                  {
                      Numar = Numar -> Fiu[j];

                      R[MAXL - P + i] = j +'0';

                      break;
                  }
                else M -= Numar -> Fiu[j] -> Cnt;
            }
        }

        for (j = 0; j <= 9; ++j)
          if (Numar -> Fiu[j] != NULL)
            if (Numar -> Fiu[j] -> OK == M)
            {
                  R[MAXL] = j + '0';

                  break;
            }
          else --M;

        printf("%s\n", R + MAXL - P + 1);
    }

    int main()
    {
        double l = clock();

        freopen(FIN, "r", stdin);
        freopen(FOUT, "w", stdout);

        scanf("%d\n", &N);

        Init();

        for (i = 1; i <= N; ++i)
        {
            gets(s + 1); L = strlen(s + 1);

            if (s[1] == '1')
            {   
                Update(1, 1, MAXL, L - 2);

                Add(Num[MAXL - L + 2], i);
            } else
            {
                M = 0;
                for (j = 3; j <= L; ++j) M = M * 10 + s[j] - '0';

                Query(1, 1, MAXL, M);

                Print(L, M, Num[MAXL - L]);
            }
        }

        //printf("\n%lf", (clock() - l) / CLOCKS_PER_SEC);

        return 0;
    }