要找每个串的出现次数,实际上就是在fail树上进行处理了,我们知道,在fail树的祖先节点上的点,一定是在这之前的前缀的点,所以直接进行跳转就可以了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <string> 5 #include <cstring> 6 #include <algorithm> 7 #include <limits> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <set> 12 #include <map> 13 #include <bitset> 14 #include <unordered_map> 15 #include <unordered_set> 16 #define lowbit(x) ( x&(-x) ) 17 #define pi 3.141592653589793 18 #define e 2.718281828459045 19 #define INF 0x3f3f3f3f 20 #define HalF (l + r)>>1 21 #define lsn rt<<1 22 #define rsn rt<<1|1 23 #define Lson lsn, l, mid 24 #define Rson rsn, mid+1, r 25 #define QL Lson, ql, qr 26 #define QR Rson, ql, qr 27 #define myself rt, l, r 28 #define pii pair<int, int> 29 #define MP(a, b) make_pair(a, b) 30 using namespace std; 31 typedef unsigned long long ull; 32 typedef unsigned int uit; 33 typedef long long ll; 34 const int maxN = 2e5 + 7; 35 int N, tot, root; 36 struct Trie_node 37 { 38 int nex[26], fail; vector<int> val; 39 Trie_node() { memset(nex, 0, sizeof(nex)); val.clear(); fail = 0; } 40 void clear() { memset(nex, 0, sizeof(nex)); val.clear(); fail = 0; } 41 } t[maxN]; 42 char s[maxN], T[2000006]; 43 void Insert(int ith) 44 { 45 int len = (int)strlen(s), u = root; 46 for(int i=0, id; i<len; i++) 47 { 48 id = s[i] - 'a'; 49 if(!t[u].nex[id]) 50 { 51 t[u].nex[id] = ++tot; 52 t[tot].clear(); 53 } 54 u = t[u].nex[id]; 55 } 56 t[u].val.push_back(ith); 57 } 58 int que[maxN], top, tail; 59 void build_fail() 60 { 61 top = tail = 0; 62 que[tail++] = root; 63 int tmp, p, son; 64 while(top < tail) 65 { 66 tmp = que[top++]; 67 for(int i=0; i<26; i++) 68 { 69 son = t[tmp].nex[i]; 70 if(son) 71 { 72 if(!tmp) t[son].fail = 0; 73 else 74 { 75 p = t[tmp].fail; 76 while(p && !t[p].nex[i]) p = t[p].fail; 77 t[son].fail = t[p].nex[i]; 78 } 79 que[tail++] = son; 80 } 81 else t[tmp].nex[i] = t[t[tmp].fail].nex[i]; 82 } 83 } 84 } 85 vector<int> to[maxN]; 86 int siz[maxN] = {0}, maxx; 87 int ans[maxN]; 88 void dfs(int u) 89 { 90 for(int v : to[u]) 91 { 92 dfs(v); 93 siz[u] += siz[v]; 94 } 95 if(!t[u].val.empty()) 96 { 97 for(int i : t[u].val) 98 { 99 ans[i] = siz[u]; 100 } 101 } 102 } 103 int main() 104 { 105 scanf("%d", &N); 106 tot = 0; root = 0; 107 t[root].clear(); 108 for(int i=1; i<=N; i++) 109 { 110 scanf("%s", s); 111 Insert(i); 112 } 113 build_fail(); 114 for(int i=0; i<=tot; i++) { to[i].clear(); siz[i] = 0; } 115 for(int i=1; i<=tot; i++) to[t[i].fail].push_back(i); 116 scanf("%s", T); 117 int u = root, len = (int)strlen(T); 118 for(int i=0, id; i<len; i++) 119 { 120 id = T[i] - 'a'; 121 while(u && !t[u].nex[id]) u = t[u].fail; 122 u = t[u].nex[id]; 123 siz[u]++; 124 } 125 maxx = 0; 126 dfs(root); 127 for(int i=1; i<=N; i++) printf("%d ", ans[i]); 128 return 0; 129 }