constint SN = 2e6 + 100; constint SM = 26; structSAM { int trans[SN][SM], maxlen[SN], link[SN], scnt, siz[SN]; queue<int> q; int pos[SN]; SAM() { scnt = 1; }; intinsert(int id, int pre) { // if (trans[pre][id] && (maxlen[pre] + 1 == maxlen[trans[pre][id]])) // return trans[pre][id];
//bool flag = 0; int cur = ++scnt;
maxlen[cur] = maxlen[pre] + 1;
siz[cur] = 1; int u = pre, nc; //pre = cur; for (; u && !trans[u][id]; u = link[u]) trans[u][id] = cur; if (!u) link[cur] = 1; else { int x = trans[u][id]; if (maxlen[x] == maxlen[u] + 1) link[cur] = x; else { // if (u == pre) // flag = 1; nc = ++scnt; maxlen[nc] = maxlen[u] + 1; link[nc] = link[x]; link[cur] = link[x] = nc; memcpy(trans[nc], trans[x], sizeof(trans[x])); for (; u && trans[u][id] == x; u = link[u]) trans[u][id] = nc; } } return cur; } voidbuild() { //bfs遍历Trie树构造广义SAM
for (int i = 0; i < 26; ++i) if (tri.son[0][i]) q.push(tri.son[0][i]); //插入第一层字符
pos[0] = 1; //Tire树上的根0在SAM上的位置为根1 while (!q.empty()) { int x = q.front(); q.pop(); //cout << x << ' ' << (tri.fa[x]) << endl; pos[x] = insert(tri.c[x] - 'A', pos[tri.fa[x]]); //注意是pos[Trie->fa[x]] for (int i = 0; i < 26; ++i) if (tri.son[x][i]) q.push(tri.son[x][i]); } } } sam;
structedge { int to, nxt; } e[SN]; int head[SN], ecnt;
voidaddadge(int u, int v) { e[++ecnt].to = v; e[ecnt].nxt = head[u]; head[u] = ecnt; }
voiddfs(int x) {
for (int i = head[x]; i; i = e[i].nxt) { int to = e[i].to; dfs(e[i].to); sam.siz[x] += sam.siz[to]; } } char t[N]; int ed[N]; int n, m; intmain() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { char ch[3]; int op; scanf("%s %d", ch, &op); ed[i] = tri.insert(ch[0], ed[op]); } sam.build(); for (int i = 2; i <= sam.scnt; i++) addadge(sam.link[i], i); dfs(1);
for (int i = 1; i <= m; i++) { scanf("%s", t + 1); int len = strlen(t + 1); int u = 1; bool f = 1; for (int j = len; j >= 1; j--) { int id = t[j] - 'A'; if (sam.trans[u][id]) u = sam.trans[u][id]; else { f = 0; break; } } //cout << f << endl; if (f) printf("%d\n", sam.siz[u]); else printf("0\n"); } }
siz[cur] = 1; int u = pre, nc; //pre = cur; for (; u && !trans[u][id]; u = link[u]) trans[u][id] = cur; if (!u) link[cur] = 1; else { int x = trans[u][id]; if (maxlen[x] == maxlen[u] + 1) link[cur] = x; else { if (u == pre) flag = 1; nc = ++scnt; maxlen[nc] = maxlen[u] + 1; link[nc] = link[x]; link[cur] = link[x] = nc; memcpy(trans[nc], trans[x], sizeof(trans[x])); for (; u && trans[u][id] == x; u = link[u]) trans[u][id] = nc; } } return flag ? nc : cur; }
} sam;
structedge { int to, nxt; } e[SN]; int head[SN], ecnt;
voidaddadge(int u, int v) { e[++ecnt].to = v; e[ecnt].nxt = head[u]; head[u] = ecnt; }
voiddfs(int x) {
for (int i = head[x]; i; i = e[i].nxt) { int to = e[i].to; dfs(e[i].to); sam.siz[x] += sam.siz[to]; } } char t[N]; int ed[N]; int n, m; intmain() { scanf("%d%d", &n, &m); ed[0] = 1; for (int i = 1; i <= n; i++) { char ch[3]; int op; scanf("%s %d", ch, &op); ed[i] = sam.insert(ch[0] - 'A', ed[op]); }
for (int i = 2; i <= sam.scnt; i++) addadge(sam.link[i], i); dfs(1);
for (int i = 1; i <= m; i++) { scanf("%s", t + 1); int len = strlen(t + 1); int u = 1; bool f = 1; for (int j = len; j >= 1; j--) { int id = t[j] - 'A'; if (sam.trans[u][id]) u = sam.trans[u][id]; else { f = 0; break; } } //cout << f << endl; if (f) printf("%d\n", sam.siz[u]); else printf("0\n"); } }