题目链接:BZOJ - 3172

题目分析:

  题目要求求出每个单词出现的次数,如果把每个单词都在AC自动机里直接跑一遍,复杂度会很高。

  这里使用AC自动机的“副产品”——Fail树,Fail树的一个性质是,一个字符串出现的次数,就等于以它的结点为根的Fail树中的子树中所有结点的 Cnt 和。

  所以把每个单词插入的时候每个字符都 ++Cnt ,在建 Fail 的时候将结点依次压入一个栈,最后再从栈顶开始弹栈,更新栈顶元素的 Fail 的 Cnt 值,这样就是自叶子节点向上更新了。

  我开始写的时候出现的错误:建 Fail 的时候漏掉了 if (Now -> Child[i] == NULL) Now -> Child[i] = Now -> Fail -> Child[i]; 这句。这样会 RE !

代码如下:

  

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 200 + 5, MaxL = 1000000 + 5, MaxC = 26; int n, l; char Str[MaxL]; struct Trie
{
int Cnt;
Trie *Fail, *Child[MaxC];
void clear() {
Cnt = 0;
Fail = NULL;
for (int i = 0; i < 26; ++i) Child[i] = NULL;
}
} TA[MaxL], *P = TA, *Root, *Zero, *Pos[MaxN]; Trie *NewNode() {
++P;
P -> clear();
return P;
} void AC_Init() {
Zero = NewNode();
Root = NewNode();
Root -> Fail = Zero;
for (int i = 0; i < 26; ++i) Zero -> Child[i] = Root;
} Trie *Insert(char *Str, int l) {
Trie *Now = Root;
int t;
for (int i = 0; i < l; ++i) {
t = Str[i] - 'a';
if (Now -> Child[t] == NULL) Now -> Child[t] = NewNode();
Now = Now -> Child[t];
++(Now -> Cnt);
}
return Now;
} Trie *Q[MaxL], *S[MaxL];
int Head, Tail, Top; void Build_Fail() {
Top = 0;
Head = Tail = 0;
Q[++Tail] = Root;
Trie *Now;
while (Head < Tail) {
Now = Q[++Head];
S[++Top] = Now;
for (int i = 0; i < 26; ++i) {
if (Now -> Child[i] == NULL) Now -> Child[i] = Now -> Fail -> Child[i];
else {
Now -> Child[i] -> Fail = Now -> Fail -> Child[i];
Q[++Tail] = Now -> Child[i];
}
}
}
while (Top) {
Now = S[Top--];
if (Now -> Fail != NULL)
(Now -> Fail -> Cnt) += (Now -> Cnt);
}
} int main()
{
scanf("%d", &n);
AC_Init();
for (int i = 1; i <= n; ++i) {
scanf("%s", Str);
l = strlen(Str);
Pos[i] = Insert(Str, l);
}
Build_Fail();
for (int i = 1; i <= n; ++i) printf("%d\n", Pos[i] -> Cnt);
return 0;
}

  

  

[BZOJ 3172] [Tjoi2013] 单词 【AC自动机】的更多相关文章

  1. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3198  Solved: 1532[Submit][Status ...

  2. bzoj 3172: [Tjoi2013]单词 AC自动机

    3172: [Tjoi2013]单词 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  3. BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树

    题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...

  4. BZOJ 3172 [Tjoi2013]单词 AC自己主动机(fail树)

    题意:链接 方法:AC自己主动机与fail树性质 解析:复习AC自己主动机的第一道题?(真正的第一题明明是又一次写了遍hdu2222! ) 这题说实话第一眼看上去就是个sb题,仅仅要建出来自己主动机. ...

  5. BZOJ 3172([Tjoi2013]单词-后缀数组第一题+RMQ)

    3172: [Tjoi2013]单词 Time Limit: 10 Sec   Memory Limit: 512 MB Submit: 268   Solved: 145 [ Submit][ St ...

  6. 【BZOJ 3172】[Tjoi2013]单词 AC自动机

    关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...

  7. bzoj 3172: [Tjoi2013]单词【AC自动机】

    一眼AC自动机,就是先把串建一个自动机,标记每个串在自动机上的位置,然后加上间隔符连成一个串在自动机上跑,每跑到一个点就说明这个串以及它到root的所有点表示的串都要被更新一次 先在点上打上标记,最后 ...

  8. 【BZOJ3172】[Tjoi2013]单词 AC自动机

    [BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...

  9. bzoj 3172 [Tjoi2013]单词(fail树,DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3172 [题意] 题目的意思是这样的,给若干个单词,求每个单词在这一堆单词中的出现次数. ...

随机推荐

  1. 一、Bitmap的recycle问题

    尽管Android有自己的垃圾回收机制,对于是不是要我们自己调用recycle,还的看情况而定.假设仅仅是使用少量的几张图片,回收与否关系不大.但是若有大量bitmap须要垃圾回收处理,那必定垃圾回收 ...

  2. hdu5294||2015多校联合第一场1007 最短路+最大流

    http://acm.hdu.edu.cn/showproblem.php? pid=5294 Problem Description Innocent Wu follows Dumb Zhang i ...

  3. Qt 学习之路:QML 组件

    前面我们简单介绍了几种 QML 的基本元素.QML 可以由这些基本元素组合成一个复杂的元素,方便以后我们的重用.这种组合元素就被称为组件.组件就是一种可重用的元素.QML 提供了很多方法来创建组件.不 ...

  4. java输入输出

    1. import java.io.*;//写进文档,然后又在显示器显示出来.public class fileinputstream{public static void main(String[] ...

  5. Java中ArrayList问题:删除一个ArrayList中的重复元素,注意留意一个问题

    该问题有两种方法: 一 利用两个数组,此法简单,不讨论 二 利用一个数组,从第0个开始依次取元素,并在其后元素中查找是否有该元素,有则删掉后面的重复元素,依次遍历.---但是这种情况要特别注意,当后续 ...

  6. 关于黑名单IP的设置

    最近在做一个项目的时候,需要做一个自动的黑名单设置,也就是将一天内重复出错的超过一定次数的手机号,和IP给加入黑名单里面,下次请求的时候先判断是否在黑名单里. 这个是获取IP地址的方法 private ...

  7. SQL语句优化(分享)

    一.操作符优化 1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用 ...

  8. vs2013下的WCFRest 模板开发WCF

    在vs2013下使用wcfRestservice40 是安装不成功的,尝试多遍,都是这样.查看以前vs2012做的wcfrest,经过调教,终于在vs2013下也可以了! 1.新建wcf服务应用程序 ...

  9. ASP.net MVC 多语言处理

    MVC多语言处理主要分两部分,一部分是Razor视图中的文字标签内容切换, 另一部分是javascript文件中的文标签内容切换.  这里分这两部分来说. View视图中的比较好做, 思路是使用资源文 ...

  10. UTF-8和GBK有什么区别?

    字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1. 至于UTF-8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码.对于英文字符 ...