AC自动机

PS:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html

PS:http://www.cnblogs.com/kuangbin/category/402395.html


#include<iostream>

#include<cstdio>
#include<string.h>
#include<string>
#include<set>
#include<algorithm>
#include<cmath>
#include<queue>

#define ll __int64
#define MAX 1000009

const int maxnode = MAX;
const int sigma_size = 26;
using namespace std;

struct Trie
{
    int ch[maxnode][sigma_size];
    int val[maxnode];
    int next[maxnode];
    int sz,root;
    int idx(char c)
    {
        return c - 'a';
    }
    int newnode()
    {
        for(int i = 0; i<26; i++)
            ch[sz][i] = 0;
        val[sz++] = 0;
        return sz - 1;
    }
    void init()
    {
        sz = 0;
        root = newnode();
    }
    void Insert(char* s)
    {
        int u = root;
        int n = strlen(s);
        for(int i = 0; i<n; i++)
        {
            int c = idx(s[i]);
            if(!ch[u][c])
                ch[u][c] = newnode();
            u = ch[u][c];
        }
        val[u]++;
    }
    void build()
    {
        queue<int>Q;
        next[root] = root;
        for(int i = 0; i<26; i++)
        {
            if(!ch[root][i])
            {
                ch[root][i] = root;
            }
            else
            {
                next[ch[root][i]] = root;
                Q.push(ch[root][i] );
            }
        }
        while(!Q.empty())
        {
            int now = Q.front();
            Q.pop();
            for(int i = 0; i<26; i++)
            {
                if(!ch[now][i])
                {
                    ch[now][i] = ch[next[now]][i];
                }
                else
                {
                    next[ch[now][i]] = ch[next[now]][i];
                    Q.push(ch[now][i]);
                }
            }
        }
    }
    int query(char* s)
    {
        int len = strlen(s);
        int now = root;
        int res = 0;
        for(int i = 0; i<len; i++)
        {
            int c = idx(s[i]);
            now = ch[now][c];
            int temp = now;
            while(temp!= root)
            {
                res+=val[temp];
                val[temp] = 0;
                temp = next[temp];
            }
        }
        return res;
    }
    void debug()
    {
        for(int i = 0; i<sz; i++)
        {
            printf("id = %3d,next = %3d,val = %3d,chi = [",i,next[i],val[i]);
            for(int j = 0; j < 26; j++)
                printf("%2d",ch[i][j]);
            printf("]\n");
        }
    }
};

char str[MAX];
Trie Ac;

int main()
{
    int T;
    int n;
    scanf("%d",&n);
    Ac.init();
    for(int i = 0; i<n; i++)
    {
        scanf("%s",str);
        Ac.Insert(str);
    }
    Ac.build();
    scanf("%s",str);
    // Ac.debug();
    if(Ac.query(str)>0)
    {
        puts("YES");
    }
    else
    {
        puts("NO");
    }
    return 0;
}

你可能感兴趣的:(AC自动机)