您的位置:首页 > 其它

AC自动机模板

2014-05-14 13:22 190 查看
贴份模板

胡大神和崔大神的组合模板

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 1000010
#define LL long long
#define INF 0xfffffff
#define maxch 26
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = ~0u>>2;
const int child_num = 26;
char ss
;
class ACAutomation
{
private:
int ch
[maxch];
int val
;
int fail
;
int Q
;
int id[128];
int sz;
// int dp[2]
[1<<10];
public:
void init()
{
fail[0] = 0;
for(int i = 0 ; i < child_num;  i++)
id[i+'a'] = i;
}
void reset()//初始化
{
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
sz = 1;
}
void insert(char *a,int key)//建立trie树
{
int p = 0;
for( ; *a ; a++)
{
int c = id[*a];
if(ch[p][c]==0)
{
memset(ch[sz],0,sizeof(ch[sz]));
val[sz] = 0;
ch[p][c] = sz++;
}
p = ch[p][c];
}
val[p] += key;
}
void construct()//构建fail指针
{
int head = 0,tail = 0,i;
for(i = 0 ;i < child_num ; i++)
{
if(ch[0][i])
{
fail[ch[0][i]] = 0;
Q[tail++] = ch[0][i];
}
}
while(head!=tail)
{
int u = Q[head++];
for(i = 0 ;i < child_num ;i ++)
{
if(ch[u][i]!=0)
{
Q[tail++] = ch[u][i];
fail[ch[u][i]] = ch[fail[u]][i];
}
else
ch[u][i] = ch[fail[u]][i];
}
}
}
int work(char *s)
{
int k = strlen(s);
int p = 0,ans = 0;
for(int i = 0; i < k ; i++)
{
int d = s[i]-'a';
p = ch[p][d];
int tmp = p;
while(tmp!=0&&val[tmp]!=0)
{
ans+=val[tmp];
val[tmp] = 0;
tmp = fail[tmp];
}
}
return ans;
}

}ac;
int main()
{
int t,n;
char word[55];
ac.init();
cin>>t;
while(t--)
{
cin>>n;
ac.reset();
while(n--)
{
scanf("%s",word);
ac.insert(word,1);
}
ac.construct();
scanf("%s",ss);
printf("%d\n",ac.work(ss));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: