Title Description

Alice has n strings S_1,s_2...s_n,bob has a string set T, and the first collection is empty. The next thing that happens is the Q operation, which has two forms: "1 P", and Bob adds a string P to his own collection. "2 X", Alice asks Bob how many strings in a collection T contain string s_x. (We call string A contains string B, and if and only if B is a substring of a) Bob is in trouble and needs your help.

Input

Line 1th, a number n; next n lines, one string per line for s_i, next line, one number q, next Q line, one operation per line, format for the title description.

Output

For each Alice query, help Bob output the answer.

Sample input

3

A

Bc

Abc

5

1 ABCA

2 1

1 BCA

2 2

2 3

Sample output

1

2

1

Exercises

AC Automaton + Tree chain with +dfs sequence + tree-like array

The substring of P is represented by the suffix of the prefix, and all suffixes of a prefix are represented on the AC automaton as: the trie tree on the node of the prefix corresponding to the node of the root node.

So for all s strings to establish AC automata, to find the fail tree, then add a P string, it contains the range of S string is p on the trie tree each position (p each prefix) fail tree to the root node covered by all nodes, that is, the tree chain and +1.

All locations are sorted by DFS sequence, each point to the root node path +1, each adjacent two points LCA to the root node path-1. The query is to check the single-point weight value. Need to support: to the root node of the path Plus, single-point evaluation, after the difference into a single point plus, sub-tree evaluation, using DFS to transform the subtree into an interval, and then use a tree-like array to maintain the interval and can.

Time Complexity $O (n\log N) $.

#include <queue> #include <cstdio> #include <algorithm> #define N 100010#define M 2000010using namespace Std;queue<int> q;int c[m][26], fail[m], tot = 1, pos[n], head[m], to[m], next[m], CNT, fa[m][20], DEEP[M], log[m], vp[m], lp[m], TP, F[m], val[m], Tv;char str[m];void build () {int x, i;for (i = 0; i <; i + +) C[0][i] = 1;q.push (1), while (!q.empty ()) {x = Q.front (), Q.pop (); for (i = 0; i <; i + +) {if (C[x][i]) fail[c[x][i ]] = C[fail[x]][i], Q.push (C[x][i]); else c[x][i] = C[fail[x]][i];}}} inline void Add (int x, int y) {to[++cnt] = y, next[cnt] = head[x], head[x] = cnt;} void Dfs (int x) {int i;vp[x] = ++tp;for (i = 1; I <= log[deep[x]]; i + +) fa[x][i] = fa[fa[x][i-1]][i-1];for (i = He AD[X]; I i = Next[i]) fa[to[i]][0] = x, deep[to[i]] = deep[x] + 1, DFS (To[i]); lp[x] = TP;} inline int LCA (int x, int y) {int i;if (deep[x] < deep[y]) swap (x, y), for (i = log[deep[x]-deep[y], ~i; i--) if (DE EP[X]-deep[y] >= (1 << i) x = fa[x][i];if (x = = y) return x;for (i = log[deep[x]]; ~i; i--) if (Deep[x] >= (1 << i) && Fa[x][i] ! = Fa[y][i]) x = fa[x][i], y = Fa[y][i];return fa[x][0];} inline void fix (int x, int a) {int i;for (i = x; I <= tp; i + = i & i) f[i] + = A;} inline int query (int x) {int I, ans = 0;for (i = x; i; i-= i & i) ans + = F[i];return ans;} BOOL CMP (int a, int b) {return vp[a] < vp[b];} int main () {int n, m, I, J, T, opt, x;scanf ("%d", &n), for (i = 1; I <= n; i + +) {scanf ("%s", str), t = 1;f or (j = 0; str[j]; j + +) {if (!c[t][str[j]-' a ']) c[t][str[j]-' a '] = ++tot;t = c[t][str[j]-' a '];} Pos[i] = t;} Build (); for (i = 2; I <= tot; i + +) Add (Fail[i], i), log[i] = log[i >> 1] + 1;DFS (1); scanf ("%d", &m); whi Le (M--) {scanf ("%d", &opt), if (opt = = 1) {scanf ("%s", str), t = 1, TV = 0;for (i = 0; str[i]; i + +) T = c[t][str[ I]-' a '], val[++tv] = T;sort (val + 1, val + TV + 1, CMP), for (i = 1; i <= TV; i + +) fix (vp[val[i]], 1), for (i = 1; i < TV; i + +) fix (Vp[lca (Val[i], val[i + 1])],-1);} Else scanf ("%d", &x), printf ("%d\n", Query (Lp[pos[x])-query (Vp[pos[x]]-1));} return 0;}

"bzoj3881" [Coci2015]divljak ac automaton + tree chain with +dfs sequence + tree-like array