#include #include #include #include #include bool debug = false; struct beseda { char * niz; long pomem; long int idx; }; static int compar_words (const void * aa, const void * bb) { const char * a = ((const struct beseda *) aa)->niz; const char * b = ((const struct beseda *) bb)->niz; if (debug) fprintf(stderr, "compar_words: %s, %s\n", a, b); for (; *a && *b && *a == *b; a++, b++); if (*a < *b) return -1; return *a > *b; } static int intlog (long n) { int log = 1; for (int dolžina = 1; dolžina < n; dolžina *= 2) log++; return log; } int main () { if (getenv("DEBUG")) debug = true; long n; if (scanf("%ld", &n) == EOF) { perror("scanf n"); return 1; } struct beseda * s = (struct beseda *) malloc(n*sizeof *s); if (!s) { perror("malloc s"); return 1; } for (long i = 0; i < n; i++) { s[i].idx = i+1; if (scanf("%ms %ld", &(s[i].niz), &(s[i].pomem)) == EOF) { perror("scanf"); return 1; } } qsort(s, n, sizeof *s, compar_words); if (debug) for (long i = 0; i < n; i++) { fprintf(stderr, "s[%ld].niz = \"%s\"; s[%ld].pomem = %ld;\n", i, s[i].niz, i, s[i].pomem); } int log = intlog(n); // fprintf(stderr, "log: %d\n", log); long * max = (long *) malloc((n*log)*sizeof *max); if (!max) { perror("malloc max"); return 1; } for (int i = 0; i < log; i++) { for (long j = 0; j < n; j++) { if (i == 0) { max[i*n+j] = j; continue; } if (j+(1 << (i-1)) >= n) { max[i*n+j] = max[(i-1)*n+j]; continue; } max[i*n+j] = s[max[(i-1)*n+j+(1 << (i-1))]].pomem > s[max[(i-1)*n+j]].pomem ? max[(i-1)*n+j+(1 << (i-1))] : max[(i-1)*n+j]; } } long m; if (scanf("%ld", &m) == EOF) { perror("scanf m"); return 1; } long * o = (long *) malloc(m*sizeof *o); for (long i = 0; i < m; i++) { char buf[200000]; char bu2[200000]; struct beseda prefix = { .niz = buf, .pomem = 0, .idx = 0 }; struct beseda nextprefix = { .niz = bu2, .pomem = 0, .idx = 0 }; if (scanf("%s", buf) == EOF) { perror("scanf buf"); return 1; } if (debug) fprintf(stderr, "krneki: %s\n", buf); strcpy(bu2, buf); nextprefix.niz[strlen(nextprefix.niz)-1]++; long l = 0, d = n; if (compar_words(&prefix, s+n-1) > 0) l = d = n; else if (compar_words(&prefix, s) < 0) l = d = 0; else { while (l < d) { long m = (l+d)/2; switch (compar_words(&prefix, s+m)) { case -1: d = m-1; break; case 1: l = m+1; break; case 0: l = d = m; break; default: assert(false); } } if (strncmp(s[l].niz, prefix.niz, strlen(prefix.niz)) != 0) l++; assert(l<=n); } long start = l; if (debug) fprintf(stderr, "found start = %ld;\n", start); l = 0, d = n; if (compar_words(&nextprefix, s+n-1) > 0) l = d = n; else if (compar_words(&nextprefix, s) < 0) l = d = 0; else { while (l < d) { long m = (l+d)/2; switch (compar_words(&nextprefix, s+m)) { case -1: d = m-1; break; case 1: l = m+1; break; case 0: l = d = m; break; default: assert(false); } } if (compar_words(&nextprefix, s+l) > 0) { if (debug) fprintf(stderr, "l++;\n"); l++; } } long end = l; if (debug) fprintf(stderr, "found end = %ld;\n", end); if (end-start == 1) { o[i] = start; continue; } long winsizelog = intlog(end-start)-1; o[i] = -1; if (winsizelog) { if (debug) fprintf(stderr, "winsizelog: %ld, (1 << (winsizelog-1)): %ld, max[(winsizelog-1)*n+start]: %ld, max[(winsizelog-1)*n+(end-(1 << (winsizelog-1)))]: %ld\n", winsizelog, (1L << (winsizelog-1)), max[(winsizelog-1)*n+start], max[(winsizelog-1)*n+(end-(1 << (winsizelog-1)))]); o[i] = s[max[(winsizelog-1)*n+(end-(1 << (winsizelog-1)))]].pomem > s[max[(winsizelog-1)*n+start]].pomem ? max[(winsizelog-1)*n+(end-(1 << (winsizelog-1)))] : max[(winsizelog-1)*n+start]; } if (debug) fprintf(stderr, "o[%ld] = %ld;\n", i, o[i]); } for (long i = 0; i < m; i++) { if (o[i] >= 0) printf("%ld\n", s[o[i]].idx); else printf("0\n"); } }