zoukankan      html  css  js  c++  java
  • AC自动机 LA 4670 Dominating Patterns

    题目传送门

    题意:训练指南P216

    分析:求出现最多次数的字串,那么对每个字串映射id,cnt记录次数求最大就可以了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 150 + 5;
    const int NODE = N * 70;
    const int LEN = 1e6 + 5;
    const int SIZE = 26;
    struct AC   {
        int ch[NODE][SIZE], fail[NODE], val[NODE], cnt[N], sz;
        map<string, int> ms;
        void clear(void)    {
            memset (ch[0], 0, sizeof (ch[0]));
            memset (cnt, 0, sizeof (cnt));
            sz = 1; val[0] = 0;
            ms.clear ();
        }
        int idx(char c) {
            return c - 'a';
        }
        void insert(char *P, int id)    {
            ms[string (P)] = id;
            int u = 0;
            for (int c, i=0; P[i]; ++i)    {
                c = idx (P[i]);
                if (!ch[u][c])  {
                    memset (ch[sz], 0, sizeof (ch[sz]));
                    val[sz] = 0;    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            val[u] = id;
        }
        void build(void)    {
            queue<int> que; fail[0] = -1;
            int u;
            for (int i=0; i<SIZE; ++i)  {
                u = ch[0][i];
                if (u)  {
                    fail[u] = 0;    que.push (u);
                }
            }
            while (!que.empty ())   {
                u = que.front ();   que.pop ();
                for (int i=0; i<SIZE; ++i)  {
                    int &v = ch[u][i];
                    if (!v) {
                        v = ch[fail[u]][i]; continue;
                    }
                    que.push (v);
                    fail[v] = ch[fail[u]][i];
                }
            }
        }
        void query(char *T)  {
            int u = 0, v;
            for (int c, i=0; T[i]; ++i)    {
                c = idx (T[i]);
                u = ch[u][c];   v = u;
                cnt[val[v]]++;
            }
        }
    }ac;
    char pattern[N][75], text[LEN];
    int n;
    
    void solve(void)    {
        int best = -1;
        for (int i=1; i<=n; ++i)    {
            if (ac.cnt[i] > best)   best = ac.cnt[i];
        }
        printf ("%d
    ", best);
        for (int i=1; i<=n; ++i)    {
            if (ac.cnt[ac.ms[string (pattern[i])]] == best)   {
               printf ("%s
    ", pattern[i]);
            }
        }
    }
    
    int main(void)    {
        while (scanf ("%d", &n) == 1) {
            if (!n) break;
            ac.clear ();
            for (int i=1; i<=n; ++i) {
                scanf ("%s", &pattern[i]);
                ac.insert (pattern[i], i);
            }
            ac.build ();
            scanf ("%s", &text);
            ac.query (text);
            solve ();
        }
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    编程思想之正则表达式
    SQL查询顺序
    hibernate inverse属性的作用
    介绍一下Hibernate的二级缓存
    JSON数据
    你没玩过的全新版本!Win10这些骚操作你知多少
    VSCode 小鸡汤 第01期
    Editor REST Client
    k8s常用命令
    【项目3-2】多肉植物网站
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5123692.html
Copyright © 2011-2022 走看看