• AC自动机 HDOJ 2222 Keywords Search


    题目链接

    题意:每个文本串的出现次数

    分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零。   新模板,加上last跑快一倍

    #include <bits/stdc++.h>
    
    struct AC {
        static const int NODE = 10000 * 50 + 5;
        static const int SIZE = 26;
        int ch[NODE][SIZE], fail[NODE], last[NODE];
        int end[NODE];
        int sz;
        
        void clear() {
            memset (ch[0], 0, sizeof (ch[0]));
            end[0] = 0;
            sz = 1;
        }
        int idx(char ch) {
            return ch - 'a';
        }
        void insert(char *str) {
            int u = 0;
            for (int c, i=0; str[i]; ++i) {
                c = idx (str[i]);
                if (!ch[u][c]) {
                    memset (ch[sz], 0, sizeof (ch[sz]));
                    end[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            end[u]++;
        }
        void build() {
            fail[0] = 0;
            std::queue<int> que;
            for (int c=0; c<SIZE; ++c) {
                int u = ch[0][c];
                if (u) {
                    fail[u] = 0;
                    last[u] = 0;
                    que.push (u);
                }
            }
            while (!que.empty ()) {
                int r = que.front (); que.pop ();
                for (int c=0; c<SIZE; ++c) {
                    int u = ch[r][c];
                    if (!u) {
                        ch[r][c] = ch[fail[r]][c];
                    } else {
                        fail[u] = ch[fail[r]][c];
                        last[u] = end[fail[u]] ? fail[u] : last[fail[u]];
                        que.push (u);
                    }
                }
            }
        }
        int query(char *text) {
            int ret = 0, u = 0;
            for (int c, i=0; text[i]; ++i) {
                c = idx (text[i]);
                u = ch[u][c];
                int t = u;
                while (t) {
                    ret += end[t];
                    end[t] = 0;
                    t = last[t];
                }
            }
            return ret;
        }
    };
    AC ac;
    char p[55], t[1000010];
    
    int main(void)    {     //HDOJ 2222 Keywords Search
        int T;  scanf ("%d", &T);
        while (T--) {
            int n;   scanf ("%d", &n);
            ac.clear ();
            for (int i=1; i<=n; ++i)    {
                scanf ("%s", p);    ac.insert (p);
            }
            ac.build ();    scanf ("%s", t);
            printf ("%d
    ", ac.query (t));
        }
    
        return 0;
    }
    编译人生,运行世界!
  • 相关阅读:
    聊天工具分享bug
    Git命令查看代码提交次数
    短链接生成实例
    .Net MVC用户注册验证码
    js写验证码
    笔记
    jq获取数组中的某个字段拆分成字符串。
    IIS部署后中文Cookie乱码
    C#反射(Reflection)与特性(Attribute)实例
    jmm
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4737729.html
Copyright © 2020-2023  润新知