美文网首页信息学竞赛题解(IO题解)
BZOJ-3172: [Tjoi2013]单词(AC自动机解法)

BZOJ-3172: [Tjoi2013]单词(AC自动机解法)

作者: AmadeusChan | 来源:发表于2018-10-16 20:24 被阅读0次

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3172

之前这道题用SA水过了,刚学AC自动机,就先拿这道题当例题练练手吧。。。

论IO优化的重要性

4e4a20a4462309f746e3fc66700e0cf3d7cad632.jpg.png

上面那个未加优化,下面那个加了优化。。。

代码(第一次写,虽然有点丑。。。):

#include <cstdio>
#include <algorithm>
#include <cstring>
 
using namespace std ; 
 
#define MAXL 2000010
#define MAXN 210
#define MAXV 1000010
 
struct node {
        node *child[ 26 ] , *fail ;
        int cnt ;
        node (  ) {
               cnt = 0 ; memset( child , 0 ,sizeof( child ) ) ; fail = NULL ;
        }
} *roof = new( node ) , *q[ MAXV ] , *w[ MAXN ] ;
 
int getstr( char *s ) {
        int len = 0 , ch ;
        for ( ch = getchar(  ) ; ! ( ch >= 'a' && ch <= 'z' ) ; ch = getchar(  ) ) ;
        s[ len ++ ] = ch ;
        for ( ch = getchar(  ) ; ch >= 'a' && ch <= 'z' ; ch = getchar(  ) ) s[ len ++ ] = ch ;
        return len ;
}
 
void getint( int &t ) {
    int ch ;
    for ( ch = getchar(  ) ; ! ( ch >= '0' && ch <= '9' ) ; ch = getchar(  ) ) ;
    t = ch - '0' ;
    for ( ch = getchar(  ) ; ch >= '0' && ch <= '9' ; ch = getchar(  ) ) t *= 10 , t += ch - '0' ;
}
   
void putint( int t ) {
    if ( ! t ) putchar( '0' ) 
    ; else {
        int ans[ 20 ] ;
        ans[ 0 ] = 0 ;
        for ( ; t ; t /= 10 ) ans[ ++ ans[ 0 ] ] = t % 10 ;
        for ( int i = ans[ 0 ] ; i ; i -- ) putchar( '0' + ans[ i ] ) ;
    }
    putchar( '\n' );
}
 
char s[ MAXL ] ;
int n ;
 
int main(  ) {
        getint( n ) ;
        for ( int i = 0 ; i ++ < n ; ) {
               int len = getstr( s ) ;
               node *t = roof ;
               for ( int j = 0 ; j < len ; j ++ ) {
                       if ( ! t -> child[ s[ j ] - 'a' ] ) t -> child[ s[ j ] - 'a' ] = new( node ) ;
                       t = t -> child[ s[ j ] - 'a' ] ; t -> cnt ++ ;
               }
               w[ i ] = t ;
        }
        int head = 0 , tail = 0 ;
        for ( int i = 0 ; i < 26 ; i ++ ) if ( roof -> child[ i ] ) {
               q[ ++ tail ] = roof -> child[ i ] ; q[ tail ] -> fail = roof ;
        }
        while ( head < tail ) {
               node *v = q[ ++ head ] ;
               for ( int i = 0; i < 26; i ++ ) if ( v -> child[ i ] ) {
                       node *u = v -> fail ; q[ ++ tail ] = v -> child[ i ] ;
                       for ( ; u != roof && ! u -> child[ i ] ; u = u -> fail ) ;
                       q[ tail ] -> fail = u -> child[ i ] ? u -> child[ i ] : roof ;
               }
        }
        for ( int i = tail ; i ; i -- ) q[ i ] -> fail -> cnt += q[ i ] -> cnt ;
        for ( int i = 0 ; i++ < n ; ) putint( w[ i ] -> cnt ) ;
        return 0 ;
}

相关文章

  • BZOJ-3172: [Tjoi2013]单词(AC自动机解法)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3172 之...

  • AC自动机 专题整理

    AC自动机学习记录 参考资料 字典树(讲解+模版)AC自动机算法AC自动机算法详解hdu 2222 ac自动机入门...

  • 自动AC机?不,是AC自动机

    今天我们来介绍一点进阶的知识——AC自动机。 AC自动机是啥 AC自动机是什么呢?是不是用了这个算法,不管什么题目...

  • AC自动机实现屏蔽单词

    多模式自动匹配AC自动机 KMP是多模式匹配算法, 解决的是一个字符串匹配多个模式串的问题, 该字符串往往短于或者...

  • 【AC自动机】AC自动机可以帮你自动AC吗

    参考博文:AC自动机算法详解 (转载) (原文作者:DarkRaven,原文的链接失效了)图片来源:AC自动机算...

  • AC自动机-去除敏感字符

    AC自动机 AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名...

  • lucene中文分词

    IK中文分词 DoubleArrayTrie的AC自动机

  • 字符串算法小结

    hash kmp和ac自动机 后缀数组,后缀自动机,后缀树 扩展kmp manacher算法 回文自动机 可删改的...

  • AC 自动机

    AC自动机 AC自动机是一个经典的多模式串匹配算法,它可以实现对主串的一次扫描来匹配多个模式串的功能。实现AC自动...

  • 回文树(附模板题URAL-1960)

    (最好事先学习过kmp,Trie,AC自动机)回文树,有效解决各类回文问题的超级666的树形结构 集AC自动机的f...

网友评论

    本文标题:BZOJ-3172: [Tjoi2013]单词(AC自动机解法)

    本文链接:https://www.haomeiwen.com/subject/bykkzftx.html