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;
}


posted @ 2015-08-17 16:04  buzhidaohahaha  阅读(209)  评论(0编辑  收藏  举报