hdu5384(AC自动机)
哇,ac自动机好快呀!看的是匡斌的模板,自己有些了一遍,这个链接该怎么贴呢?这样可以吗?
kuangbin的模板:http://download.csdn.net/detail/howe_young/8112607,感觉kuagnbin写的模板很干净。
一开始写这道题时,想着ac自动机占的空间太大了,写不了,比赛完了后,现在才发现,开一个差不多大的数组就可以了,不用那么较真
(今天中午和队友一起吃的是蛋汁牛肉饭,因为其他的牛肉饭都有胡萝卜,虽然米饭中有很多牛肉汤在泡着米饭,但是米饭有点硬,如果米饭再香一点,软一点,汤再少一点应该会更好吃吧!队友说泡菜味的面挺好吃的。)
2015.8.29:
又把ac自动机的过程想了一下,理顺了一下,大概就是模板,根据题中不同的意思,再做相应的改变。
(面包陪那个泡菜味的面挺好吃的,小的时候喜欢吃米饭,因为在北方,米饭不常吃,但是自从住校以后,就喜欢吃饼了,喜欢吃饼沾麻酱,我们那有一句话,叫大葱蘸酱,越吃越胖,不知道是哪种酱,还是指所有的!
)
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
#define N 100010
#define M 26
#define X 10010
char sentencea[N][X];
char worda[X];
struct AC{
int nexta[N][M];
int faila[N];
int enda[N];
int L;
int root;
int newnode(){
for(int i=0;i<M;i++){
nexta[L][i]=-1;
}
enda[L++]=0;
return L-1;
}
void init(){
L=0;
root=newnode();
}
void assert(char word[]){
int now=root;
for(int i=0;word[i]!='\0';i++){
int tempch=word[i]-'a';
if(nexta[now][tempch]==-1){
nexta[now][tempch]=newnode();
}
now=nexta[now][tempch];
}
enda[now]++;
}
void build(){
queue<int> q;
for(int i=0;i<M;i++){
if(nexta[root][i]==-1){
nexta[root][i]=root;//nexta[root][i]都不存在了,哪还有什么root一直到nexta[root][i]都相等这一说,所以当然不存在fail[nexta[root][i]]?乖,回去重新比较!
}
else{
faila[nexta[root][i]]=root;//这里nexta[root][i]已经非-1了,不需要重新赋值,但是由于nexta[root][i]是存在的所以存在一种可能从root一直到nexta[root][i]一直相等,所以好吧,给你个fail[nexta[root][i]]
q.push(nexta[root][i]);
}
}
while(!q.empty()){
int temp=q.front();
q.pop();
for(int i=0;i<M;i++){
if(nexta[temp][i]==-1){
nexta[temp][i]=nexta[faila[temp]][i];
}
else{
faila[nexta[temp][i]]=nexta[faila[temp]][i];
q.push(nexta[temp][i]);
}
}
}
}
long long int query(char sentence[]){
int now=root;
long long int ans=0;
for(int i=0;sentence[i]!='\0';i++){//printf("wo shi da hao ren");
now=nexta[now][sentence[i]-'a'];
int temp=now;
while(temp!=root){
ans+=(long long int)enda[temp];
temp=faila[temp];
}
}
return ans;
}
};
AC ac;//为什么这个必须定义到外面?
int main(){
int t;
int n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
//AC ac;
ac.init();
for(int i=0;i<n;i++){
scanf("%s",sentencea[i]);
}
for(int i=0;i<m;i++){
scanf("%s",worda);
ac.assert(worda);
}
ac.build();
for(int i=0;i<n;i++){
printf("%lld\n",ac.query(sentencea[i]));
}
}
return 0;
}

浙公网安备 33010602011771号