1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include <bits/stdc++.h> using namespace std; #define N 200007
int ch[N][26], trie_num;
int fail[N]; vector<int> son[N];
int trie_add[N], lens[N]; vector<int> rec[N];
void insert(char *s, int id) { lens[id] = strlen(s); int p = 0; for (int i = 0; i < lens[id]; i++) { int x = s[i] - 'a'; rec[id].push_back(x); if (!ch[p][x]) ch[p][x] = ++trie_num; p = ch[p][x]; } trie_add[id] = p; }
void get_fail() { queue<int> que; for (int i = 0; i < 26; i++) if (ch[0][i]) fail[ch[0][i]] = 0, que.push(ch[0][i]); while (!que.empty()) { int p = que.front(); que.pop(); son[fail[p]].push_back(p); for (int i = 0; i < 26; i++) if (ch[p][i]) fail[ch[p][i]] = ch[fail[p]][i], que.push(ch[p][i]); else ch[p][i] = ch[fail[p]][i]; } }
int dfs_l[N], dfs_r[N], dfs_num; void dfs(int x) { dfs_l[x] = ++dfs_num; for (auto i : son[x]) dfs(i); dfs_r[x] = dfs_num; }
int root[N]; struct node { int l, r, val; } tree[N << 5]; int tree_num;
void change(int &p, int q, int l, int r, int add) { p = ++tree_num, tree[p] = tree[q]; tree[p].val++; if (l == r) return; int mid = (l + r) >> 1; if (add <= mid) change(tree[p].l, tree[q].l, l, mid, add); else change(tree[p].r, tree[q].r, mid + 1, r, add); }
void build(int &root_p, int root_q, int id) { int p = 0, q = root_q; for (int i = 0; i < lens[id]; i++) { p = ch[p][rec[id][i]]; change(root_p, q, 1, dfs_num, dfs_l[p]); q = root_p; } }
int query(int p, int q, int l, int r, int L, int R) { if (L <= l && r <= R) return tree[p].val - tree[q].val; int mid = (l + r) >> 1, ret = 0; if (L <= mid) ret += query(tree[p].l, tree[q].l, l, mid, L, R); if (R > mid) ret += query(tree[p].r, tree[q].r, mid + 1, r, L, R); return ret; }
char s[N]; int main() { int n, q; scanf("%d%d", &n, &q); for (int i = 1; i <= n; i++) { scanf("%s", s); insert(s, i); } get_fail(); dfs(0); for (int i = 1; i <= n; i++) build(root[i], root[i - 1], i); int l, r, k; while (q--) { scanf("%d%d%d", &l, &r, &k); printf("%d\n", query(root[r], root[l - 1], 1, dfs_num, dfs_l[trie_add[k]], dfs_r[trie_add[k]])); } return 0; }
|