BZOJ2780 [Spoj]8093 Sevenk Love Oimaster 【广义后缀自动机】

题目

 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<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#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<<s[i]<<' '; 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;
}

posted @ 2018-03-10 12:21  Mychael  阅读(197)  评论(0编辑  收藏  举报