zoukankan      html  css  js  c++  java
  • UVALive 4670 AC自动机

    第二道AC自动机的题目了,之前参考的是网上一个博客算法,不怎么好,难写而且占空间

    后来参照大白书做的这题,代码简洁多了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <map>
    #include <string>
    #include <queue>
    #define N 12000
    using namespace std;
    map<string,int> mc; //防止模板里出现重复的
    struct AutoTrie
    {
        int ch[N][28];
        int val[N];
        int f[N];
        int cnt[N];
        int last[N];
        int sz;
        void init()
        {
            memset(ch[0],0,sizeof ch[0]);
            memset(cnt,0,sizeof cnt);
            //memset(val,0,sizeof val);
            //memset(f,0,sizeof f);
            mc.clear();
            sz=1;
        }
        int idx(char c)
        {
            return c-'a';
        }
        void insert(char* s,int v)
        {
            int u=0;
            int n=strlen(s);
            for (int i=0; i<n; i++)
            {
                int c=idx(s[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]=v;
            mc[string(s)]=v;
        }
        void print(int j)
        {
            if (j)
            {
                cnt[val[j]]++;
                print(last[j]);
            }
        }
        void find(char *T)
        {
            int j=0;
            int n=strlen(T);
            for (int i=0; i<n; i++)
            {
                int c=idx(T[i]);
                while (j && !ch[j][c]) j=f[j];
                j=ch[j][c];
                if (val[j]) print(j);
                else if (last[j])
                    print(last[j]);
            }
        }
        void build ()
        {
            queue<int> q;
            f[0]=0;
            for (int c=0; c<26; c++)
            {
                int u=ch[0][c];
                if (u)
                {
                    f[u]=0;
                    last[u]=0;
                    q.push(u);
                }
            }
            while (!q.empty())
            {
                int r=q.front();
                q.pop();
                for (int c=0; c<26; c++)
                {
                    int u=ch[r][c];
                    if (!u) continue;
                    q.push(u);
                    int v=f[r];
                    while (v && !ch[v][c]) v=f[v];
                    f[u]=ch[v][c];
                    last[u]=val[f[u]]?f[u]:last[f[u]];
                }
            }
        }
    };
    AutoTrie ac;
    char cc[160][80];
    char T[1000010];
    int main()
    {
        int n;
        while (scanf("%d",&n))
        {
            if (!n) break;
            ac.init();
            for (int i=1; i<=n; i++)
            {
                scanf("%s",cc[i]);
                ac.insert(cc[i],i);
            }
            ac.build();
            scanf("%s",T);
            ac.find(T);
            int sum=-1;
            for (int i=1; i<=n; i++)
            {
                if (ac.cnt[i]>sum) sum=ac.cnt[i];
               // cout<<i<<" "<<ac.cnt[i]<<endl;
            }
            printf("%d
    ",sum);
            for (int i=1; i<=n; i++)
            {
                if (ac.cnt[mc[string(cc[i])]]==sum)
                {
                    printf("%s
    ",cc[i]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    c.vim
    Ubuntu18.04重装指南
    [TJOI2017]城市 【树的直径+暴力+优化】
    [Bzoj3696]化合物【暴力+树形Dp】
    [JLOI2015]战争调度【暴力+树形Dp】
    [Bzoj3743][Coci2015] Kamp【换根Dp】
    [POI2017]Sabota【观察+树形Dp】
    [CQOI2009]叶子的染色【性质+树形Dp】
    COCI2014/2015 Contest#1 D MAFIJA【基环树最大独立点集】
    [牛客网] 推箱子【离散,线段树区间覆盖】
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3659643.html
Copyright © 2011-2022 走看看