标签:cst 更新 atom min namespace ant owa recommend ota
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define MAX 100001 using namespace std; int pos; int trie[MAX][26],fail[MAX] = {-1},sum[MAX]; char s[100001][10001]; void Insert_Str(char *s) {///字符串插入到字典树中 int i = -1,r = 0; while(s[++ i]) { int d = s[i] - ‘a‘; if(!trie[r][d]) { trie[r][d] = ++ pos; } r = trie[r][d]; } sum[r] ++; } void Build_Fail() {///通过父结点的Fail更新子结点的Fail queue<int> q; q.push(0); while(!q.empty()) { int id = q.front(); q.pop(); for(int i = 0;i < 26;i ++) { if(trie[id][i]) {///第i个儿子存在 int temp = fail[id];///temp赋值当前节点的Fail while(temp != -1) { if(trie[temp][i]) { fail[trie[id][i]] = trie[temp][i]; break; } temp = fail[temp]; } q.push(trie[id][i]); } } } } void Ac_automation(int k) { int i = -1,r = 0,ans = 0; while(s[k][++ i]) { int d = s[k][i] - ‘a‘; while(r && !trie[r][d]) r = fail[r];///如果没有匹配的子结点 就找它的Fail看看有没有匹配的子结点 if(trie[r][d]) r = trie[r][d]; int temp = r; while(temp) { ans += sum[temp]; temp = fail[temp];///找最长后缀 } } printf("%d\n",ans); } int main() { char str[10001]; int t,n,m; scanf("%d",&t); while(t --) { pos = 0; memset(trie,0,sizeof(trie)); memset(fail + 1,0,sizeof(fail)); memset(sum,0,sizeof(sum)); scanf("%d %d",&n,&m); for(int i = 0;i < n;i ++) { scanf("%s",s[i]); } for(int i = 0;i < m;i ++) { scanf("%s",str); Insert_Str(str); } Build_Fail(); for(int i = 0;i < n;i ++) { Ac_automation(i); } } return 0; }
标签:cst 更新 atom min namespace ant owa recommend ota
原文地址:https://www.cnblogs.com/8023spz/p/9798811.html