zoukankan      html  css  js  c++  java
  • UvaLive 4670 Dominating Patterns

    二次联通门 : UvaLive 4670 Dominating Patterns

    /*
        UvaLive 4670 Dominating Patterns 
    
        AC自动机
        
        题目大意
        有个由小写字母组成的模式串以及一个文本串。
        每个模式串可能会在文本串中出现多次。
        你需要找出哪些模式串在文本串中出现的次数最多。 
        
        注意可能会有多组相同的模式串
        
        加个数组判一判就好了。。
        
        具体是在Trie树中的叶节点维护一个small_number
        表示最早的串
        
        之后计数什么的, 都记到这个上 
    */
    #include <cstring>
    #include <cstdio>
    #include <queue>
    
    #define Max 1000009
    
    bool read (int &now)
    {
        now = 0;
        register char word = getchar ();
        while (word < '0' || word > '9')
            word = getchar ();
        while (word >= '0' && word <= '9')
        {
            now = now * 10 + word - '0';
            word = getchar ();
        }
        return now > 0;
    }
    
    inline int max (int a, int b)
    {
        return a > b ? a : b;
    }
    
    struct Trie_Data
    {
    
        Trie_Data *Fail;
        Trie_Data *child[26];
        
        int small_number;
        Trie_Data ()
        {
            for (int i = 0; i < 26; i ++)
                this->child[i] = NULL;
                
            this->Fail = NULL;
            small_number = 0;
        }    
    };
    
    Trie_Data *Root;
    
    int number[Max / 1000];
    int count[Max / 1000];
    
    char line[Max / 1000][Max / 1000];
    char Need[Max];
    
    int Answer;
    
    class AC_Type
    {
        private :
            
            int __Count_;
    
        public :
        
            void Clear ()
            {
                __Count_ = 0;
                memset (number, 0, sizeof (number));
                memset (count, 0, sizeof count);
            }
            
            void Insert (char *key)
            {
                int Len = strlen (key);
                __Count_ ++;
                
                Trie_Data *now = Root, *pos;
                int Id;
                
                for (int i = 0; i < Len; i ++)
                {
                    Id = key[i] - 'a';
                    if (now->child[Id] == NULL)
                        now->child[Id] = new Trie_Data;
                    now = now->child[Id];
                }
                if (!now->small_number)
                    now->small_number = __Count_;
                number[__Count_] = now->small_number;
            }
            
            void Build_AC ()
            {
                std :: queue <Trie_Data *> Queue;
                
                Queue.push (Root);  
                Trie_Data *now, *pos;
                while (!Queue.empty ())
                {
                    pos = NULL;
                    now = Queue.front ();
                    Queue.pop ();
                    
                    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.push (now->child[i]); 
                    }  
                }
            }
            
            void Query (char *key)
            {
                Trie_Data *now = Root, *pos;
                
                int Len = strlen (key);
                int Id;
                
                for (int i = 0; i < Len; i ++)
                {
                    Id = key[i] - 'a';
                    for (; now != Root && now->child[Id] == NULL; now = now->Fail);
                    
                    now = now->child[Id];
                    if (now == NULL)
                        now = Root;
                    for (pos = now; pos != Root; pos = pos->Fail)
                        count[pos->small_number] ++;
                }
            }
    };
    
    AC_Type Make;
    
    int main (int argc, char *argv[])
    {
        int N;
        for (int N; read (N); )
        {
            Root = new Trie_Data;
            Make.Clear ();
            for (register int i = 1; i <= N; i ++)
            {
                scanf ("%s", line[i]);
                Make.Insert (line[i]); 
            }
            Make.Build_AC ();
            scanf ("%s", Need);
            Make.Query (Need);
            Answer = 0;
            for (int i = 1; i <= N; i ++)
                Answer = max (Answer, count[i]);
            printf ("%d
    ", Answer);
            for (int i = 1; i <= N; i ++)
                if (count[number[i]] == Answer)
                    puts (line[i]);
        }    
        return 0;
    }
  • 相关阅读:
    yum 下载安装包以及依赖包
    《将博客搬至CSDN》
    Lucene
    Solr
    LVS原理详解(3种工作模式及8种调度算法)
    正向代理与反向代理
    网关,网卡
    NAT地址转换
    Nginx学习总结
    网络_OSI模型_数据包传输
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/6979464.html
Copyright © 2011-2022 走看看