zoukankan      html  css  js  c++  java
  • 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
    ", AC.ans[pos[i]]);
    	}
     	return 0;
    }
    

      

  • 相关阅读:
    eclipse中的debug模式的使用
    Hibernate快速入门
    鸟哥的 Linux 私房菜Shell Scripts篇(四)
    Vim命令图解及快捷键讲解
    SpringBoot文档
    鸟哥的 Linux 私房菜Shell Scripts篇(三)
    鸟哥的 Linux 私房菜Shell Scripts篇(二)
    (二)IDEA使用,快捷键
    (一)IDEA使用,基础配置
    idea-git同步服务器代码后撤销操作
  • 原文地址:https://www.cnblogs.com/Heilce/p/7402951.html
Copyright © 2011-2022 走看看