• 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;
    }
  • 相关阅读:
    推荐!国外程序员整理的 PHP 资源大全
    PHPSTORM/IntelliJ IDEA 常用 设置配置优化
    PHPStorm下XDebug配置
    MySQL修改root密码的多种方法
    php 修改上传文件大小 (max_execution_time post_max_size)
    phpstorm8注册码
    Linux提示no crontab for root的解决办法
    网站的通用注册原型设计
    解决mysql出现“the table is full”的问题
    通过php下载文件并重命名
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/7041206.html
Copyright © 2020-2023  润新知