• ac自动机 模板


    自己写的0.0

     1 #include <queue>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 
     6 struct AC_auto
     7 {
     8     const static int LetterSize = 26;
     9     const static int TrieSize = 26 * ( 1e5 + 50);
    10 
    11     int tot,root,fail[TrieSize],end[TrieSize],next[TrieSize][LetterSize];
    12 
    13     int newnode(void)
    14     {
    15         memset(next[tot],-1,sizeof(next[tot]));
    16         end[tot] = 0;
    17         return tot++;
    18     }
    19 
    20     void init(void)
    21     {
    22         tot = 0;
    23         root = newnode();
    24     }
    25 
    26     int getidx(char x)
    27     {
    28         return x - 'a';
    29     }
    30 
    31     void insert(char *ss)
    32     {
    33         int len = strlen(ss);
    34         int now = root;
    35         for(int i = 0; i < len; i++)
    36         {
    37             int idx = getidx(ss[i]);
    38             if(next[now][idx] == -1)
    39                 next[now][idx] = newnode();
    40             now = next[now][idx];
    41         }
    42         end[now]++;
    43     }
    44 
    45     void build(void)
    46     {
    47         queue<int>Q;
    48         fail[root] = root;
    49         for(int i = 0; i < LetterSize; i++)
    50             if(next[root][i] == -1)
    51                 next[root][i] = root;
    52             else
    53                 fail[next[root][i]] = root,Q.push(next[root][i]);
    54         while(Q.size())
    55         {
    56             int now = Q.front();Q.pop();
    57             for(int i = 0; i < LetterSize; i++)
    58             if(next[now][i] == -1)   next[now][i] = next[fail[now]][i];
    59             else
    60                 fail[next[now][i]] = next[fail[now]][i],Q.push(next[now][i]);
    61         }
    62     }
    63 
    64     int match(char *ss)
    65     {
    66         int len,now,res;
    67         len = strlen(ss),now = root,res = 0;
    68         for(int i = 0; i < len; i++)
    69         {
    70             int idx = getidx(ss[i]);
    71             int tmp = now = next[now][idx];
    72             while(tmp)
    73             {
    74                 res += end[tmp];
    75                 end[tmp] = 0;//按题目修改
    76                 tmp = fail[tmp];
    77             }
    78         }
    79         return res;
    80     }
    81     void debug()
    82     {
    83         for(int i = 0;i < tot;i++)
    84         {
    85             printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
    86             for(int j = 0;j < LetterSize;j++)
    87                 printf("%3d",next[i][j]);
    88             printf("]
    ");
    89         }
    90     }
    91 };
    92 int main(void)
    93 {
    94 
    95 
    96     return 0;
    97 }

     从网上扒的:

    //======================
    // HDU 2222
    // 求目标串中出现了几个模式串
    //====================
    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    #include <string.h>
    #include <queue>
    using namespace std;
    
    struct Trie
    {
        int next[500010][26],fail[500010],end[500010];
        int root,L;
        int newnode()
        {
            for(int i = 0;i < 26;i++)
                next[L][i] = -1;
            end[L++] = 0;
            return L-1;
        }
        void init()
        {
            L = 0;
            root = newnode();
        }
        void insert(char buf[])
        {
            int len = strlen(buf);
            int now = root;
            for(int i = 0;i < len;i++)
            {
                if(next[now][buf[i]-'a'] == -1)
                    next[now][buf[i]-'a'] = newnode();
                now = next[now][buf[i]-'a'];
            }
            end[now]++;
        }
        void build()
        {
            queue<int>Q;
            fail[root] = root;
            for(int i = 0;i < 26;i++)
                if(next[root][i] == -1)
                    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 < 26;i++)
                    if(next[now][i] == -1)
                        next[now][i] = next[fail[now]][i];
                    else
                    {
                        fail[next[now][i]]=next[fail[now]][i];
                        Q.push(next[now][i]);
                    }
            }
        }
        int query(char buf[])
        {
            int len = strlen(buf);
            int now = root;
            int res = 0;
            for(int i = 0;i < len;i++)
            {
                now = next[now][buf[i]-'a'];
                int temp = now;
                while( temp != root )
                {
                    res += end[temp];
                    end[temp] = 0;
                    temp = fail[temp];
                }
            }
            return res;
        }
        void debug()
        {
            for(int i = 0;i < L;i++)
            {
                printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
                for(int j = 0;j < 26;j++)
                    printf("%2d",next[i][j]);
                printf("]
    ");
            }
        }
    };
    char buf[1000010];
    Trie ac;
    int main()
    {
        int T;
        int n;
        scanf("%d",&T);
        while( T-- )
        {
            scanf("%d",&n);
            ac.init();
            for(int i = 0;i < n;i++)
            {
                scanf("%s",buf);
                ac.insert(buf);
            }
            ac.build();
            scanf("%s",buf);
            printf("%d
    ",ac.query(buf));
        }
        return 0;
    }
    struct AC_Auto{
        const static int LetterSize = 26;
        const static int TrieSize = 26 * ( 1e5 + 50); 
        int tot;
        int fail[TrieSize]; 
        int suffixlink[TrieSize]; 
    
        struct node{
            int ptr[LetterSize];
            int val;
        }tree[TrieSize];
    
        inline int GetLetterIdx(char c){
            return c - 'a';
        }
    
        void init_node(node & s){
            memset( s.ptr , 0 , sizeof( s.ptr ) );
            s.val = 0;
        }
    
        void find(const char * str){
            int len = strlen( str );
            int j = 0;
            for(int i = 0 ; i < len ; ++ i){
                int idx = GetLetterIdx( str[i] );
                while(j && !tree[j].ptr[idx]) j = fail[j];
                j = tree[j].ptr[idx];
                if(suffixlink[j]) minv[i] = suffixlink[j];
                else minv[i] = 0;
            }
        }
    
        void insert(const char * str){
            int len = strlen( str );
            int cur = 0;
            for(int i = 0 ; i < len ; ++ i){
                int idx = GetLetterIdx( str[i] );
                if(!tree[cur].ptr[idx]){
                    tree[cur].ptr[idx] = tot;
                    init_node( tree[tot++] );
                }
                cur = tree[cur].ptr[idx];
            }
            if(tree[cur].val == 0) tree[cur].val = len;
            else tree[cur].val = min( tree[cur].val , len );
        }
    
        void build_fail(){
            queue < int > Q; // 开在栈中 , 如果节点数较多 , 可设为全局变量
            suffixlink[0] = fail[0] = 0;
            for(int i = 0 ; i < LetterSize ; ++ i)
                if(tree[0].ptr[i]){
                    int index = tree[0].ptr[i];
                    fail[index] = 0 , suffixlink[index] = tree[index].val;
                    Q.push( index );
                }
            while(!Q.empty()){
                int x = Q.front() ; Q.pop();
                for(int i = 0 ; i < LetterSize ; ++ i)
                    if(tree[x].ptr[i]){
                        int v = tree[x].ptr[i];
                        int j = fail[x];
                        while( j && !tree[j].ptr[i] ) j = fail[j];
                        fail[v] = tree[j].ptr[i];
                        suffixlink[v] = suffixlink[fail[v]];
                        if(suffixlink[v] == 0){
                            if(suffixlink[x]) suffixlink[v] = suffixlink[x] + 1;
                        }
                        else if(suffixlink[x]) suffixlink[v] = min( suffixlink[v] , suffixlink[x] + 1 );
                        if(tree[v].val){
                            if(suffixlink[v]==0) suffixlink[v] = tree[v].val;
                            else suffixlink[v] = min( suffixlink[v] , tree[v].val );
                        }
                        Q.push( v );
                    }
            }
        }
    
        void init(){ tot = 1 ; init_node( tree[0] );}
    
    }ac_auto;
  • 相关阅读:
    云游四海
    保持良好的人际关系,赢得好人缘的八大诀窍
    二十三格经典的管理定律(建议收藏)
    游北湖公园有感
    如何成为领袖? 学习任正非小沃森郭士纳
    梦回江南
    观野花展有感
    爱一个人要爱多久
    醉卧山林
    游环岛路有感
  • 原文地址:https://www.cnblogs.com/weeping/p/5936736.html
Copyright © 2020-2023  润新知