题目链接: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. spring beans源码解读之--BeanFactory进化史

    BeanFactory是访问bean容器的根接口,它是一个bean容器的基本客户端视图. 先让我们看看beanfactory的前生后世吧! beanFactory有四个重要的子接口: SimpleJn ...

  2. JavaScript的变量提升

    在JavaScript中,var变量具有函数级作用域,而且是整个函数作用域.为什么会是整个函数作用域呢?因为var变量具有变量(声明)提升功能,能将变量声明隐式的提升到函数体的顶部.这样做的一个好处就 ...

  3. 后端接收不到AngularJs中$http.post发送的数据的问题

    1.问题: 后端接收不到AngularJs中$http.post发送的数据,总是显示为null 示例代码: $http.post(/admin/KeyValue/GetListByPage, { pa ...

  4. Java实现文件拷贝的4种方法.

    原文地址:http://blog.csdn.net/ta8210/article/details/2073817 使用 java 进行文件拷贝 相信很多人都会用,,不过效率上是否最好呢? 最近看了看N ...

  5. Java——(七)Map之HashMap和Hashtable实现类

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- Map Map用于具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里的ke ...

  6. Android之如何混淆代码和相关配置

    昨天,客户想看一下目前项目开发到什么程度了,于是需要将项目签名打包成apk,结果打包的时候出错了,吃惊,什么情况.等成功打包以后,安装起来发现部分功能又报错了,囧,所幸最后还是解决了.在这里记录一下遇 ...

  7. SQL SERVER将指定表中的指定字段按照(,)逗号分隔

    不开心呀,早知道不跳了,一跳跳坑里来了. 使用方式: DECLARE @ConsigneeAddressId INT; SET @ConsigneeAddressId = 1; SELECT  * F ...

  8. 解决kernel headers报错

    Make sure you have updated version $ sudo apt-get update Search for kernel version (optional) $ apt- ...

  9. IOS开发网络篇之──ASIHTTPRequest详解

    目录 目录 发起一个同步请求 创建一个异步请求 队列请求 请求队列上下文 ASINetworkQueues, 它的delegate提供更为丰富的功能 取消异步请求 安全的内存回收建议 向服务器端上传数 ...

  10. Sqoop import加载HBase过程中,遇到Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x

    在执行hbase sqoop抽取的时候,遇到了一个错误,如下图: 在执行程序的过程中,遇到权限问题很正常,也容易让人防不胜防,有问题就想办法解决,这个是关键. 解决办法如下: 第一步:su hdfs, ...