您的位置:首页 > 其它

HDU2896-AC自动机

2017-05-20 00:04 162 查看
*直接AC自动机模板然后搜索每一个子串中的失配位置里面有没有是某个之前输入字符串的结尾有就加入进去并且在字符串的结尾标记上是第几个字符如果不是结尾就标记为0

题目链接

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
#define mes(s) memset(s,0,sizeof(s))
#define rec(i,a,n) for(i = a; i <= n; i++)
#define dec(i,a,n) for(i = n; i >= a; i--)
using namespace std;
const int mx = 1e5+10;
set<int>st;
struct trie{
int ch[mx][128];
int v[mx];
int f[mx];
int last[mx];
int sz;
void init() {sz = 1,mes(ch[0]),mes(v),mes(v),mes(last);}
int idx(char c) { return c;}
void insert(int id,char *s){
int len = strlen(s)-1;
int u = 0,i;
rec(i,0,len){
int d = idx(s[i]);
if(!ch[u][d]){
mes(ch[sz]);
ch[u][d] = sz++;
}
u = ch[u][d];
}
v[u] = id;
}
void getfail(){
int i,d,u;
queue<int>q;
rec(i,0,127){
if(!ch[0][i])
ch[0][i] = 0;
else{
f[ch[0][i]] = 0;
last[ch[0][i]] = 0;
q.push(ch[0][i]);
}
}
while(!q.empty()){
u = q.front();
q.pop();
rec(d,0,127){
if(!ch[u][d]){
ch[u][d] = ch[f[u]][d];
continue;
}
f[ch[u][d]] = ch[f[u]][d];
last[ch[u][d]] = v[f[ch[u][d]]]?f[ch[u][d]]:last[f[ch[u][d]]];
q.push(ch[u][d]);
}
}
}
void find(char *s){
int i,u = 0,len = strlen(s)-1;
rec(i,0,len){
int d = idx(s[i]);
int ret = ch[u][d];
while(ret){
if(v[ret])
st.insert(v[ret]);
ret = last[ret];
}
u = ch[u][d];
}
}
}word;
char s[mx];
int main(){
int n,m;
int i,j,k;
while(~scanf("%d",&n)){
word.init();
getchar();
rec(i,1,n){
gets(s);
word.insert(i,s);
}
word.getfail();
scanf("%d",&m);
getchar();
int ans = 0;
rec(i,1,m){
gets(s);
st.clear();
word.find(s);
if(st.size()){
ans++;
printf("web %d:",i);
for(auto it = st.begin(); it != st.end(); it++)
printf(" %d",*it);
puts("");
}
}
printf("total: %d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: