• BZOJ 3172: [Tjoi2013]单词


    二次联通门 : BZOJ 3172: [Tjoi2013]单词

    /*
        BZOJ 3172:[Tjoi2013]单词
     
        终于有一道水题了。。。。
    
        AC自动机
        利用fail树的性质
    
        每次插入时, 统计每个字符的出现次数
    
        然后建立AC自动机
    
        后倒着跑一边,把当前点的和加到它的fail指针上
    
        后输出即可
     
    */
    #include <cstdio>
    #include <cstring>
    
    #define Max 1000005
    
    void read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word > '9' || word < '0')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
    }
    
    struct T_D 
    {
        T_D *child[26];
        
        T_D *Fail;
    
        int number;
        int Count;
    
        T_D ()
        {
            number = 0;
    
            for (int i = 0; i < 26; i ++)
                this->child[i] = NULL;
            
            Count = 0;
            Fail = NULL;
        }
    
    };
    
    T_D *Queue[Max];
    
    int Answer[Max];
    
    class AC_Type
    {
    
        private :
    
            T_D *Root;
    
            int Trie_Count;
            
            int Head, Tail;
        public :
    
            AC_Type ()
            {
                Root = new T_D;
                Root->number = ++ Trie_Count;    
            }
    
            void Insert (char *key, int &x)
            {
                int Len = strlen (key);
                T_D *now, *pos;
    
                now = Root;
                int Id;
    
                for (int i = 0; i < Len; i ++)
                {
                    Id = key[i] - 'a';
                    if (now->child[Id] == NULL)
                    {
                        now->child[Id] = new T_D;
                        now->child[Id]->number = ++ Trie_Count;
                    }
                    Answer[now->child[Id]->number] ++;
                    now = now->child[Id];
                }
                x = now->number;
            }
    
            void Build_AC ()
            {
                
                T_D *now, *pos;
    
                Head = 0, Tail = 0;
                Queue[++ Tail] = Root;
    
                while (Head != Tail)
                {
                    Head ++;
                    now = Queue[Head];
                    
                    pos = NULL;
    
                    for (int i = 0; i < 26; i ++)
                    {
                        if (now->child[i] == NULL)
                            continue;
                        if (now == Root)
                            now->child[i]->Fail = Root;
                        else
                        {
                            for (pos = now->Fail; pos; pos = pos->Fail)
                                if (pos->child[i])
                                {
                                    now->child[i]->Fail = pos->child[i];
                                    break;
                                }
                            if (pos == NULL)
                                now->child[i]->Fail = Root;
                        }
                        Queue[++ Tail] = now->child[i];    
                    }
                }
            }
    
            void Solve ()
            {
                for (int i = Tail; i; i --)
                    if (Queue[i]->Fail)
                        Answer[Queue[i]->Fail->number] += Answer[Queue[i]->number];
            }
    };
    
    AC_Type Make;
    
    char line[Max];
    int to[Max];
    
    int main (int argc, char *argv[])
    {
    
        int N;
        read (N);
    
        for (int i = 1; i <= N; i ++)
        {
            scanf ("%s", line);
            Make.Insert (line, to[i]);
        }
        
        Make.Build_AC ();
    
        Make.Solve ();
        for (int i = 1; i <= N; i ++)
            printf ("%d
    ", Answer[to[i]]);
    
        return 0;
    }
  • 相关阅读:
    今天学到的单词
    今天是运维的一天
    今天是属于数据库的一天
    Python基础9 元组的访问和拆包
    Python基础8 元组的创建
    Python基础7 序列
    Python基础6 控制语句 if else elif range() while for
    Python基础5 运算符
    Python基础4 字符串的查找 find rfind 字符串类型和数字类型的转换
    Python基础2 数据类型:数字类型
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7041206.html
Copyright © 2020-2023  润新知