AC自动机80pts求助
查看原帖
AC自动机80pts求助
808180
HDS_Acenaphthylene楼主2023/8/21 19:34
#include <bits/stdc++.h>
using namespace std;
int edge[5005][26], cnt[5005], fail[5005], fa[5005], r[5005];
string s[55], t[55];
char v[5005];
int n, m, top;
queue<int> q;
int len[5005];bool vis[5005];
int f[2000005];
int dfs(int x){
	if(x == 0)
		return 0;
	if(vis[x])
		return len[x];
	vis[x] = 1;
	return len[x] |= dfs(fail[x]);
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n;i ++)
		cin >> s[i];
	for (int i = 1;i <= m;i ++) 
		cin >> t[i];
	for (int i = 1; i <= n; i++) {
		int now = 0;
		for (int j = 0; j < s[i].size();j ++) {
			if (!edge[now][s[i][j] - 'a'])						 // 建边
				edge[now][s[i][j] - 'a'] = ++top, fa[top] = now; // 建立节点
			now = edge[now][s[i][j] - 'a'];
			if (j + 1 == s[i].size())
				len[now] = 1 << (s[i].size() - 1);
			v[now] = s[i][j];
		}
	}
	q.push(0);
	while (!q.empty()) {
		int f = q.front();
		q.pop();
		for (int i = 0; i < 26; i++)
			if (edge[f][i])
				q.push(edge[f][i]);
		if (fa[f] != 0) {
			int tmp = fail[fa[f]];
			while (!edge[tmp][v[f] - 'a'] && tmp)
				tmp = fail[tmp];
			fail[f] = edge[tmp][v[f] - 'a'];
			r[fail[f]]++;
		}
	}
	for(int i = 1;i <= top;i ++)
		if(r[i] == 0)
			dfs(i);
	for(int i = 1;i <= m;i ++){
		int now = 0;
		f[0] = 0;
		for(int j = 0;j < t[i].size();j ++) {
			if(!edge[now][t[i][j] - 'a'])
				while(!edge[now][t[i][j] - 'a'] && now)
					now = fail[now];
			now = edge[now][t[i][j] - 'a'];
			f[j] = f[j - 1];
			for(int i = 0;i < 20;i ++)
				if(len[now] & (1 << i))
					f[j] = max(f[j], f[j - i - 1] == j - i? j + 1 : f[j - i - 1]);
		}
		cout << f[t[i].size() - 1] <<endl;
	}
	return 0;
}

链接

2023/8/21 19:34
加载中...