zoukankan      html  css  js  c++  java
  • UVa Live 4670 Dominating Patterns

    题目传送门

      快速的通道I

      快速的通道II

    题目大意

      给定一堆短串,和一个文本串,问哪些短串在文本串中出现的次数最多。

      我觉得刘汝佳的做法,时间复杂度有问题。只是似乎这道题短串串长太短不好卡。比如给出的串是一坨$a$。暴力跳$last$会比较gg。

      考虑如何计算一个短串在长串中的出现次数。

      当短串在长串的某个位置出现的时候,这意味着它的结束位置在fail树上的祖先中某个状态是短串的终止状态。

      我们会在长串经过的每个状态都去做这样一个操作来统计每个短串出现的次数。

      这个可以看成在fail树上的以根为端点的链上修改操作。

      由于询问可以看成是离线的,所以每次可以单点修改cnt,最后做一次前缀和。

    Code

      1 /**
      2  * UVa Live
      3  * Problem#4670
      4  * Accepted
      5  * Time: 45ms
      6  */
      7 #include <iostream>
      8 #include <cstring>
      9 #include <cstdio>
     10 #include <queue>
     11 using namespace std;
     12 typedef bool boolean;
     13 
     14 const int MaxNode = 10505, N = 152, L = 75;
     15 
     16 typedef class TrieNode {
     17     public:
     18         int cnt;
     19         TrieNode* ch[26];
     20         TrieNode* fail;
     21 }TrieNode;
     22 
     23 TrieNode pool[MaxNode];
     24 TrieNode *top;
     25 
     26 TrieNode* newnode() {
     27     top->cnt = 0;
     28     memset(top->ch, 0, sizeof(top->ch));
     29     top->fail = NULL;
     30     return top++;
     31 }
     32 
     33 typedef class AhoCorasick {
     34     public:
     35         TrieNode* rt;
     36 
     37         AhoCorasick() {
     38             top = pool;
     39             rt = newnode();
     40         }
     41 
     42         TrieNode* insert(char* str) {
     43             TrieNode* p = rt;
     44             for (int i = 0, c; str[i]; i++) {
     45                 c = str[i] - 'a';
     46                 if (!p->ch[c])
     47                     p->ch[c] = newnode();
     48                 p = p->ch[c];
     49             }
     50             return p;
     51         }
     52 
     53         void build() {
     54             queue<TrieNode*> que;
     55             rt->fail = NULL;
     56             que.push(rt);
     57             while (!que.empty()) {
     58                 TrieNode* p = que.front();
     59                 que.pop();
     60                 for (int i = 0; i < 26; i++) {
     61                     TrieNode *np = p->ch[i];
     62                     if (!np)    continue;
     63                     que.push(np);
     64                     TrieNode* f = p->fail;
     65                     while (f && !f->ch[i])    f = f->fail;
     66                     if (!f)
     67                         np->fail = rt;
     68                     else
     69                         np->fail = f->ch[i];
     70                 }
     71             }
     72         }
     73 
     74         void query(char *str) {
     75             TrieNode *p = rt;
     76             for (int i = 0; str[i]; i++) {
     77                 int c = str[i] - 'a';
     78                 while (p && !p->ch[c])    p = p->fail;
     79                 if (!p)
     80                     p = rt;
     81                 else
     82                     p = p->ch[c];
     83                 p->cnt++;    
     84             }
     85             for (p = top - 1; p != pool; p--)
     86                 p->fail->cnt += p->cnt;
     87         }
     88 }AhoCorasick;
     89 
     90 int n;
     91 AhoCorasick ac;
     92 char S[1000005];
     93 char T[N][L];
     94 TrieNode* ps[N];
     95 
     96 inline boolean init() {
     97     scanf("%d", &n);
     98     if (!n)    return false;
     99     ac = AhoCorasick();
    100     for (int i = 1; i <= n; i++) {
    101         scanf("%s", T[i]);
    102         ps[i] = ac.insert(T[i]);
    103     }
    104     scanf("%s", S);
    105     return true;
    106 }
    107 
    108 inline void solve() {
    109     ac.build();
    110     ac.query(S);
    111     int maxt = 0;
    112     for (int i = 1; i <= n; i++)
    113         if (ps[i]->cnt > maxt)
    114             maxt = ps[i]->cnt;
    115     printf("%d
    ", maxt);
    116     for (int i = 1; i <= n; i++)
    117         if (ps[i]->cnt == maxt)
    118             puts(T[i]);
    119 }
    120 
    121 int main() {
    122     while(init())
    123         solve();
    124     return 0;
    125 }
  • 相关阅读:
    再谈用java实现Smtp发送邮件之Socket编程
    Android TextView设置个别字体样式
    Spring4.0MVC学习资料,注解自己主动扫描bean,自己主动注入bean(二)
    Angular团队公布路线图,并演示怎样与React Native集成
    [LeetCode]Remove Element
    poj2481 Cows
    Spark SQL 源代码分析之Physical Plan 到 RDD的详细实现
    MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍
    容器使用笔记(List篇)
    【Java编程】建立一个简单的JDBC连接-Drivers, Connection, Statement and PreparedStatement
  • 原文地址:https://www.cnblogs.com/yyf0309/p/8640939.html
Copyright © 2011-2022 走看看