HDU 6096 AC自动机

题解:  主要的思路就是怎么能让这两个串链接起来,还有就是明白AC自动机主要处理什么问题,知道了这些这个问题就能很好的解决了。。

 

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int> P;
const int MAXN = 2000010;
int pos[MAXN];
struct Trie{
    int next[MAXN][27], fail[MAXN], LEN[MAXN], ans[MAXN];
    int root, L;
    int insert(char buf[])
    {
        int len = strlen(buf), now = 0;
        for(int i = 0; i < len; i++)
        {
            if(next[now][buf[i] - 'a'] == 0)
			{
				next[now][buf[i] - 'a'] = ++L;
				LEN[L] = i + 1;
			}
            now = next[now][buf[i] - 'a'];
        }
        return now;
    }
    void init()//不要忘记初始化
    {
        memset(next, 0, sizeof(int) * (L + 1) * 27);
        memset(fail, 0, sizeof(int) * (L + 1));
        memset(LEN, 0, sizeof(int) * (L + 1));
        memset(ans, 0, sizeof(int) * (L + 1));
		root = L = 0;
    }
    void build()
    {
        queue<int>q;
        fail[root] = root;
        for(int i = 0; i < 27; i++)
        if(next[root][i] == 0)
        next[root][i] = root;
        else
        {
            fail[next[root][i]] = root;
            q.push(next[root][i]);
        }
        while(!q.empty())
        {
            int now = q.front(); q.pop();
            for(int i = 0; i < 27; i++)
            if(next[now][i] == 0)
            next[now][i] = next[fail[now]][i];
            else
            {
                fail[next[now][i]] = next[fail[now]][i];
                q.push(next[now][i]);
            }
        }
    }
    void query(char buf[], int len)
    {
       int now = root;
        for(int i = 0; buf[i]; i++)
        {
            now = next[now][buf[i] - 'a'];
            int tmp = now;
            while(tmp != root)
            {
                if(LEN[tmp] <=  len) ans[tmp]++;
                tmp = fail[tmp];
            }
        }
    }
}AC;
char str[MAXN];
char *s[100010];
int len[100010];
char s1[100010], s2[100010];
int main()
{
	int T, n, q;
	scanf("%d", &T);
	while(T--)
	{
		AC.init();
		scanf("%d %d", &n, &q);
		int cnt = 0;
		for(int i = 0; i < n; i++)
		{
			s[i] = str + cnt;
			scanf("%s", s[i]);
			len[i] = strlen(s[i]) + 1;
			cnt += len[i];
			strcpy(str + cnt, s[i]);
			str[cnt - 1] = 'z' + 1;
			cnt += len[i];
		}
		for(int i = 0; i < q; i++)
		{
			s1[0] = 'z' + 1;
			scanf("%s%s", s1 + 1, s2);
			strcat(s2, s1);
			pos[i] = AC.insert(s2);
		}
		AC.build();
		for(int i = 0; i < n; i++)
		AC.query(s[i], len[i]);
		for(int i = 0; i < q; i++)
		printf("%d\n", AC.ans[pos[i]]);
	}
 	return 0;
}

  

posted @ 2017-08-21 10:24  Heilce  阅读(180)  评论(0编辑  收藏  举报