题目
Oimaster and sevenk love each other.But recently,sevenk heard that a girl named ChuYuXun was dating with oimaster.As a woman's nature, sevenk felt angry and began to check oimaster's online talk with ChuYuXun. Oimaster talked with ChuYuXun n times, and each online talk actually is a string.Sevenk asks q questions like this, "how many strings in oimaster's online talk contain this string as their substrings?"
输入格式
There are two integers in the first line,
the number of strings n and the number of questions q. And n lines follow, each of them is a string describing oimaster's online talk. And q lines follow, each of them is a question. n<=10000, q<=60000 the total length of n strings<=100000, the total length of q question strings<=360000输出格式
For each question, output the answer in one line.
输入样例
3 3
abcabcabc
aaa
aafe
abc
a
ca
输出样例
1
3
1
题解
广义后缀自动机裸题
先建机,然后记录每个点所被包含的字符串的个数 询问就按询问的字符串走到对应节点,输出该节点存在的字符串数#include#include #include #include #include #include #define LL long long int#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)#define REP(i,n) for (int i = 1; i <= (n); i++)#define BUG(s,n) for (int i = 1; i <= (n); i++) cout< <<' '; puts("");using namespace std;const int maxn = 200005,maxm = 400005,INF = 1000000000;inline int read(){ int out = 0,flag = 1; char c = getchar(); while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();} while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();} return out * flag;}int n;int ch[maxn][26],pre[maxn],step[maxn],cnt,last;int sz[maxn],vis[maxn];char ss[maxn >> 1];string s[10005];void ins(int x){ int p = last,np = ++cnt; step[np] = step[p] + 1; last = np; while (p && !ch[p][x]) ch[p][x] = np,p = pre[p]; if (!p) pre[np] = 1; else { int q = ch[p][x]; if (step[q] == step[p] + 1) pre[np] = q; else { int nq = ++cnt; step[nq] = step[p] + 1; for (int i = 0; i < 26; i++) ch[nq][i] = ch[q][i]; pre[nq] = pre[q]; pre[np] = pre[q] = nq; while (ch[p][x] == q) ch[p][x] = nq,p = pre[p]; } }}int main(){ n = read(); int q = read(); cnt = last = 1; for (int i = 1; i <= n; i++){ last = 1; scanf("%s",ss); int len = strlen(ss); s[i] = (string)(ss); for (int i = 0; i < len; i++) ins(ss[i] - 'a'); } int u; for (int i = 1; i <= n; i++){ u = 1; for (unsigned int j = 0; j < s[i].length(); j++){ u = ch[u][s[i][j] - 'a']; for (int p = u; p && vis[p] != i; p = pre[p]) sz[p]++,vis[p] = i; } } while (q--){ scanf("%s",ss); int len = strlen(ss),ans = 0; u = 1; for (int i = 0; i < len; i++){ if (!(u = ch[u][ss[i] - 'a'])) break; if (i == len - 1) ans = sz[u]; } printf("%d\n",ans); } return 0;}