社区讨论

用 SAM 模拟 AC 自动机,不知道为什么错了

P5357【模板】AC 自动机参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mljkw5da
此快照首次捕获于
2026/02/12 22:53
7 天前
此快照最后确认于
2026/02/13 00:41
7 天前
查看原帖
48pts
CPP
#include <bits/stdc++.h>

using namespace std;

const int N = 2e5 + 5;

int n;

string t[N], s;

struct SAM {
	struct node {
		int son[26], fa, len, siz;
	};
	
	node t[2 * N];
	
	vector <int> g[2 * N];
	
	int lst, idx;
	
	SAM() {
		lst = idx = 1;
	}
	
	void insert (char c) {
		int w = c - 'a';
		if (t[lst].son[w]) {
			int q = t[lst].son[w];
			if (t[q].len == t[lst].len + 1) {
				lst = q;
				return;
			}
			t[ ++ idx] = t[q];
			t[idx].len = t[lst].len + 1;
			t[q].fa = idx;
			int p = lst;
			while (p && t[p].son[w] == q) {
				t[p].son[w] = idx;
				p = t[p].fa;
			} 
			lst = idx;
			return;
		}
		int now = ++ idx;
		t[now].len = t[lst].len + 1;
		int p = lst;
		lst = now;
		while (p && !t[p].son[w]) {
			t[p].son[w] = now;
			p = t[p].fa;
		} 
		if (!p) {
			t[now].fa = 1;
			return;
		}
		int q = t[p].son[w];
		if (t[q].len == t[p].len + 1) {
			t[now].fa = q;
			return;
		}
		t[ ++ idx] = t[q];
		t[idx].len = t[p].len + 1;
		t[now].fa = t[q].fa = idx;
		while (p && t[p].son[w] == q) {
			t[p].son[w] = idx;
			p = t[p].fa;
		}
		return;
	} 
	
	void que (string s) {
		int at = 1;
		for (char c : s) {
			int w = c - 'a';
			while (at && !t[at].son[w]) at = t[at].fa;
			if (!at) {
				at = 1;
				continue;
			}
			at = t[at].son[w];
			++ t[at].siz;
		}
		return;
	}
	
	void dfs1 (int u) {
		for (int v : g[u]) {
			t[v].siz += t[u].siz;
			dfs1(v);
		}
		return;
	}
	
	void dfs2 (int u) {
		for (int v : g[u]) {
			dfs2(v);
			t[u].siz += t[v].siz;
		}
		return;
	}
	
	void build() {
		for (int i = 2; i <= idx; ++ i ) g[t[i].fa].push_back(i); 
	//	dfs1(1);
		dfs2(1);
	}
	
	int query (string s) {
		int at = 1;
		for (char c : s) {
			int w = c - 'a';
			if (!t[at].son[w]) return 0;
			at = t[at].son[w];
		}
		return t[at].siz;
	}
	
} T;

signed main() {
	ios :: sync_with_stdio(0), cin.tie(0), cout.tie(0);
	
	cin >> n;
	
	for (int i = 1; i <= n; ++ i ) {
		T.lst = 1;
		cin >> t[i];
		for (char c : t[i]) T.insert(c);  
	}
	
	cin >> s;
	
	T.que(s);
	T.build();
	
	for (int i = 1; i <= n; ++ i ) cout << T.query(t[i]) << '\n';
	
	return 0;
} 

回复

0 条回复,欢迎继续交流。

正在加载回复...