Cod sursa(job #1564483)

Utilizator hrazvanHarsan Razvan hrazvan Data 9 ianuarie 2016 18:26:16
Problema Nums Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <stdio.h>
#define MAXN 100000
#define BUFF (6 * (1 << 20))
FILE *out;
char s[BUFF], fol[MAXN];
int sa[MAXN], da[MAXN], dad, p;
int aib[MAXN];

inline char cif(char ch){
  if(ch >= '0' && ch <= '9')
    return 1;
  return 0;
}

inline void getind(int *p, int *st, int *dr){
  while(!cif(s[*p]))
    (*p)++;
  *st = *p;
  while(cif(s[*p]))
    (*p)++;
  *dr = (*p) - 1;
}

inline int getnr(int st, int dr){
  int rez = 0, i;
  for(i = st; i <= dr; i++){
    rez *= 10;
    rez += s[i] - '0';
  }
  return rez;
}

inline int cmp(int s1, int d1, int s2, int d2){
  if(d1 - s1 > d2 - s2)
    return 1;
  if(d1 - s1 < d2 - s2)
    return -1;
  int i = s1, j = s2;
  while(i <= d1){
    if(s[i] > s[j])
      return 1;
    if(s[i] < s[j])
      return -1;
    i++;  j++;
  }
  return 0;
}

void qs(int st, int dr){
  int i = st, j = dr, ps = sa[(st + dr) / 2], pd = da[(st + dr) / 2], aux;
  while(i <= j){
    while(cmp(ps, pd, sa[i], da[i]) == 1)
      i++;
    while(cmp(sa[j], da[j], ps, pd) == 1)
      j--;
    if(i <= j){
      aux = da[i];  da[i] = da[j];  da[j] = aux;
      aux = sa[i];  sa[i] = sa[j];  sa[j] = aux;
      i++;  j--;
    }
  }
  if(st < j)
    qs(st, j);
  if(i < dr)
    qs(i, dr);
}

inline int caut(int st, int dr, int d){
  int i = -1, pas;
  for(pas = (1 << 16); pas > 0; pas >>= 1){
    if(i + pas < d && cmp(st, dr, sa[i + pas], da[i + pas]) == 1)
      i += pas;
  }
  return i + 1;
}

inline int ultb(int x){
  return x & (-x);
}

void add(int p, int x, int d){
  if(p + ultb(p) <= d)
    add(p + ultb(p), x, d);
  aib[p] += x;
}

inline void prin(int p){
  int i;
  for(i = sa[p]; i <= da[p]; i++)
    fputc(s[i], out);
  fputc('\n', out);
}

void query(int x, int d){
  int i = 0, pas;
  for(pas = (1 << 16); pas > 0; pas >>= 1){
    if(i + pas <= d && x > aib[i + pas]){
      x -= aib[i + pas];
      i += pas;
    }
  }
  prin(i);
}

int main(){
  FILE *in = fopen("nums.in", "r");
  fread(s, BUFF, 1, in);
  fclose(in);
  int st, dr, n, i, x;
  getind(&p, &st, &dr);
  n = getnr(st, dr);
  for(i = 0; i < n; i++){
    getind(&p, &st, &dr);
    x = getnr(st, dr);
    getind(&p, &sa[dad], &da[dad]);
    if(x == 1)
      dad++;
  }
  qs(0, dad - 1);
  out = fopen("nums.out", "w");
  p = 0;
  getind(&p, &st, &dr);
  n = getnr(st, dr);
  for(i = 0; i < n; i++){
    getind(&p, &st, &dr);
    x = getnr(st, dr);
    if(x == 1){
      getind(&p, &st, &dr);
      x = caut(st, dr, dad) + 1;
      if(!fol[x]){
        add(x, 1, dad);
        fol[x] = 1;
      }
    }
    else{
      getind(&p, &st, &dr);
      x = getnr(st, dr);
      query(x, dad);
    }
  }
  fclose(out);
  return 0;
}