Cod sursa(job #1663454)

Utilizator stoianmihailStoian Mihail stoianmihail Data 25 martie 2016 23:52:26
Problema Nums Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.69 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define aibSize 131072
#define Nadejde 100000

typedef struct {
  int order;
  int pos;
  char *s;
} cell;

typedef struct {
  char *s;
  int len;
  int init;
} pair;

int N;
char number[Nadejde + 1];
cell query[Nadejde];

int aib[aibSize + 1];
char seen[Nadejde + 1];

int size;
pair sorted[Nadejde];

/** Copiaza in "str" sirul number. **/
void get(char **str, int len) {
  (*str) = (char*)calloc(len + 1, 1);
  strcpy(*str, number);
}

/** Cmp-ul pentru sort. **/
int cmp(pair X, pair Y) {
  if (X.len == Y.len) {
    return strcmp(X.s, Y.s) < 0;
  } else {
    return X.len < Y.len;
  }
}

/** Sorteaza crescator sirurile aflate in "sorted". **/
void sort(int begin, int end) {
  int b = begin, e = end;
  pair tmp, pivot = sorted[(b + e) >> 1];

  while (b <= e) {
    while (cmp(sorted[b], pivot)) {
      b++;
    }
    while (cmp(pivot, sorted[e])) {
      e--;
    }
    if (b <= e) {
      tmp = sorted[b];
      sorted[b++] = sorted[e];
      sorted[e--] = tmp;
    }
  }
  if (begin < e) {
    sort(begin, e);
  }
  if (b < end) {
    sort(b, end);
  }
}

/** Normalizeaza intrebarile. **/
void normalize() {
  int i = 0, j;

  sort(0, size - 1);
  while (i < size) {
    j = i;
    while ((j < size) && (strcmp(sorted[i].s, sorted[j].s) == 0)) {
      query[sorted[j].init].order = i + 1;
      j++;
    }
    i = j;
  }
}

/** Adauga in aib valoarea "x". **/
void add(int x) {
  do {
    aib[x]++;
    x += x & -x;
  } while (x <= aibSize);
}

/** Cauta binar in aib valoarea "val". **/
int bSearch(int val) {
  int x = 0, interval = aibSize >> 1;

  while (interval) {
    if (aib[x + interval] < val) {
      val -= aib[x += interval];
    }
    interval >>= 1;
  }
  return x + 1;
}

int main(void) {
  int i, task, loc, len;
  FILE *f = fopen("nums.in", "r");

  /* Citirea datelor. */
  fscanf(f, "%d", &N);
  for (i = 0; i < N; i++) {
    fscanf(f, "%d", &task);
    if (task == 1) {
      fscanf(f, "%s", number);
      len = strlen(number);

      get(&query[i].s, len);
      get(&sorted[size].s, len);

      sorted[size].len = len;
      sorted[size++].init = i;
      query[i].pos = task;
    } else {
      fscanf(f, "%d", &query[i].pos);
      query[i].pos <<= 1;
    }
  }
  fclose(f);

  /* Normalizarea datelor. */
  normalize();

  /* Afisarea solutiei. */
  freopen("nums.out", "w", stdout);
  for (i = 0; i < N; i++) {
    task = query[i].pos & 1;
    if (task == 1) {
      loc = query[i].order;
      if (!seen[loc]) {
        seen[loc] = 1;
        add(loc);
      }
    } else {
      loc = bSearch(query[i].pos >> 1);
      fprintf(stdout, "%s\n", sorted[loc - 1].s);
    }
  }
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}