luogu P5357 【模板】AC自动机(二次加强版)

P5357 【模板】AC自动机(二次加强版)

题目大意

给出若干模式串和一个匹配串
求每个模式串在匹配串中出现的个数

题解

所以这题和luogu P3966 [TJOI2013]单词有什么区别,直接跑完,然后统计子树大小就好辣
code:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define N 200005
#define C 26
using namespace std;
int py[N], size[N], ch[N][C], vis[N], nxt[N], ha[N], n, tot;
string st;
void insert(int id){
	int p = 0, len = st.length();
	for(int i = 0; i < len; i ++){
		if(!ch[p][st[i] - 'a']) ch[p][st[i] - 'a'] = ++ tot;
		p = ch[p][st[i] - 'a'];
	}
	py[id] = p;
}
queue<int> q;
void build(){
	for(int i = 0; i < C; i ++) if(ch[0][i]) q.push(ch[0][i]);
	while(q.size()){
		int u = q.front(); q.pop();
		ha[++ ha[0]] = u;
		for(int i = 0; i < C; i ++){
			if(ch[u][i]){
				nxt[ch[u][i]] = ch[nxt[u]][i];
				q.push(ch[u][i]);
			} else ch[u][i] = ch[nxt[u]][i];
		}
	}
}
void find(){
	int len = st.length(), p = 0;
	for(int i = 0; i < len; i ++){//直接跑
		p = ch[p][st[i] - 'a'];
		size[p] ++;
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> st;
		insert(i);
	}
	build();
	cin >> st;
	find();
	for(int i = ha[0]; i >= 1; i --) size[nxt[ha[i]]] += size[ha[i]];//统计子树大小
	for(int i = 1; i <= n; i ++) cout << size[py[i]]	 << endl;
	return 0;
}
posted @ 2019-08-09 16:52  lahlah  阅读(28)  评论(0编辑  收藏  举报