Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- uint32_t hs1(uint32_t a, uint32_t b) {
- return a + b * 1000000007;
- }
- uint32_t hs2(uint32_t a, uint32_t b) {
- return a + b * 0x7FFFFFFF;
- }
- const uint32_t hts = 1200000;
- const uint32_t nul = 0xFFFFFFFF;
- uint32_t hash_table[hts];
- uint32_t getElement(uint32_t a, uint32_t b) {
- uint32_t h1 = hs1(a, b) % hts;
- uint32_t h2 = hs2(a, b) % hts;
- if (h2 == 0)
- h2 = 1;
- for (uint32_t h = h1; ; h = h + h2) {
- if (h >= hts)
- h -= hts;
- if (hash_table[h] == nul)
- return nul;
- if ((hash_table[h] >> 17) == (h2 & 0x7FFF))
- return hash_table[h] & 0x1FFFF;
- }
- }
- void addElement(uint32_t a, uint32_t b, uint32_t x) {
- uint32_t h1 = hs1(a, b) % hts;
- uint32_t h2 = hs2(a, b) % hts;
- if (h2 == 0)
- h2 = 1;
- uint32_t h;
- for (h = h1; hash_table[h] != nul; h = h + h2, (h >= hts? h -= hts : 0)) {}
- hash_table[h] = (h2 << 17) | x;
- }
- struct node {
- uint32_t suflink_and_number;
- uint32_t prev_and_pchar;
- };
- node nodes[100001];
- uint32_t freep = 1;
- uint32_t addString(int number, FILE *f) {
- uint32_t cur = 0;
- uint32_t len = 0;
- for (;;) {
- int c = getc(f);
- if (c == 0 || c == 13 || c == 10) {
- ungetc(c, f);
- break;
- }
- assert(c != EOF);
- ++len;
- uint32_t next = getElement(cur, (uint32_t)c);
- if (next == nul) {
- next = freep++;
- nodes[next].prev_and_pchar = cur | (c << 17);
- nodes[next].suflink_and_number = nul;
- addElement(cur, c, next);
- }
- cur = next;
- }
- nodes[cur].suflink_and_number = 0x1FFFF | (number << 17);
- return len;
- }
- uint32_t suflink(uint32_t v);
- uint32_t go(uint32_t v, uint32_t c) {
- uint32_t res = getElement(v, c);
- if (res == nul) {
- if (v == 0)
- res = 0;
- else
- addElement(v, c, res = go(suflink(v), c));
- }
- return res;
- }
- uint32_t suflink(uint32_t v) {
- uint32_t res = 0x1FFFF & nodes[v].suflink_and_number;
- if (res == 0x1FFFF) {
- if (v == 0 || (nodes[v].prev_and_pchar & 0x1FFFF) == 0) {
- nodes[v].suflink_and_number ^= 0x1FFFF;
- res = 0;
- } else {
- uint32_t c = nodes[v].prev_and_pchar >> 17;
- uint32_t p = nodes[v].prev_and_pchar & 0x1FFFF;
- nodes[v].suflink_and_number ^= 0x1FFFF ^ (res = go(suflink(p), c));
- }
- }
- return res;
- }
- uint32_t number(uint32_t v) {
- if ((nodes[v].suflink_and_number >> 17) == 0x7FFF) {
- if (v == 0) {
- nodes[v].suflink_and_number ^= nul << 17;
- } else {
- nodes[v].suflink_and_number ^= (nul ^ number(suflink(v))) << 17;
- }
- }
- return nodes[v].suflink_and_number >> 17;
- }
- uint32_t len[10000];
- void skipSpaces(FILE *f) {
- while (getc(f) != '\n') {}
- }
- int main() {
- int n;
- scanf("%d", &n);
- memset(hash_table, -1, sizeof(hash_table));
- for (int i = 1; i <= n; ++i) {
- skipSpaces(stdin);
- len[i - 1] = addString(i, stdin);
- }
- int m;
- scanf("%d", &m);
- for (int l = 1; l <= m; ++l) {
- skipSpaces(stdin);
- uint32_t cur = 0;
- uint32_t mx = -1;
- for (int i = 1; ; ++i) {
- int c = getc(stdin);
- if (c == 0 || c == 13 || c == 10) {
- ungetc(c, stdin);
- break;
- }
- assert(c != EOF);
- cur = go(cur, c);
- if (number(cur)) {
- uint32_t a = i - len[number(cur) - 1] + 1;
- if (a < mx)
- mx = a;
- }
- }
- if (mx != 0xFFFFFFFF) {
- printf("%d %u\n", l, mx);
- return 0;
- }
- }
- puts("Passed");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement