您的位置:首页 > 其它

hdu5384(AC自动机)

2015-08-17 16:04 351 查看
哇,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
[X];
char worda[X];

struct AC{
int nexta
[M];
int faila
;
int enda
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: