题面:

洛谷

题解:

  很久之前做的题了,只不过之前一直90.。。。最近才发现是哪里写错了。

  我们对字符集建AC自动机。

  首先考虑一个暴力的做法,把文章当做一个长串,直接在自动机上跳,但是我们会发现,这样的复杂度可能退化到$n^2$.

  因为对于一个类似于aaaaaaaaaaaaaaaa这样的串而言,一个点的fail总是指向它的父亲,因此如果我们每次都暴力向上跳fail复杂度就不对了。

  观察到每遍历到一个节点,其实质就是给这个点到root的这条链上的每个点都+1,因此我们目标只是在fail树上对每个点都求出子树和。

  如果我们知道了所有标记的位置,显然可以建树统计一下。

  当然,也有更方便的写法,因为一个点的编号肯定比它的fail的编号大。表现在fail树上就是父亲编号比儿子小。

  所以我们从大到小枚举编号,把当前枚举到的节点的权值加给父亲即可。

  为什么这样是对的?

    因为我们可以看做是儿子先把代价给父亲,在让父亲把它的代价和它儿子的代价一起向上传。

  

  其实对于这道题而言,还有更方便的写法,你甚至不需要建匹配串。因为文章就是由给定字符集组成的,因此我们一定会遍历自动机上的每一个节点,所以与其再遍历一遍,再把每个节点权值+1,不如在建自动机的时候就直接加。

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define maxn 2500500
int n,ans[maxn],go[maxn],num;//num标记是第一个单词,便于处理单词重复的情况
int q[maxn],head,tail,tot;//从第一位开始存文本串
char s[maxn]; struct ACtree
{
int fail[maxn], c[maxn][];
//由于是统计单词在文章中的出现次数,相同单词只算一次,所以val最大只能为1
void add()//标记是第一个单词
{
int now=,len=strlen(s);
for(R i=;i<len;i++)
{
int v=s[i]-'a';
if(!c[now][v]) c[now][v]=++tot;
now=c[now][v], ++ ans[now];//因为之后再遍历也是直接遍历整个树,所以直接在这里加
}
// if(!val[now])val[now]++;//这样val就没用了
go[num]=now;//记录下每个单词的结尾部分,以防遇到重复只输出一个
} void build()
{
R now;
for(R i=; i< ;i++)
if(c[][i]) q[++tail]=c[][i];//既然fail一开始都为0,那就不用额外初始化了
while(head<tail)
{
now=q[++head];
for(R i=;i<;i++)
if(c[now][i]) fail[c[now][i]]=c[fail[now]][i],q[++tail]=c[now][i];
else c[now][i]=c[fail[now]][i];//建立虚拟节点
}
for(R i = tail; i; i --) ans[fail[q[i]]] += ans[q[i]];
for(R i = ; i <= n; i ++) printf("%d\n", ans[go[i]]);
} }AC; void pre()
{
scanf("%d",&n);
for(num=; num<=n ;num++)
scanf("%s",s), AC.add();
} int main()
{
// freopen("in.in","r",stdin);
pre();
AC.build();
// fclose(stdin);
return ;
}

  

[TJOI2013]单词 AC自动机的更多相关文章

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

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

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

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

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

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

  4. 洛谷P3966 [TJOI2013]单词(AC自动机)

    题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...

  5. [TJOI2013]单词 AC 自动机

    题目描述: 小张最近在忙毕设,所以一直在读论文. 一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 题解: AC 自动机裸题,将所有字符串读入 ...

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

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

  7. BZOJ3172[Tjoi2013]单词——AC自动机(fail树)

    题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...

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

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

  9. bzoj3172: [Tjoi2013]单词 ac自动机

    某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词 ...

随机推荐

  1. 【索引】MySQL索引

    一.索引的定义及作用 1. 二.索引的创建及删除 1.1查看表的索引 show index from tblname; 1.2.创建索引 1.22创建普通索引 ALTER TABLE `table_n ...

  2. QML和JS引擎的关系以及调用c++函数的原理

    首先推荐几篇博客 1.深入解析QML引擎, 第1部分:QML文件加载 https://www.cnblogs.com/wzxNote/p/10569535.html 2.深入解析QML引擎, 第2部分 ...

  3. RyuBook1.0案例三:REST Linkage

    REST Linkage 该小结主要介绍如何添加一个REST Link 函数 RYU本身提供了一个类似WSGI的web服务器功能.借助这个功能,我们可以创建一个REST API. 基于创建的REST ...

  4. Centos7.2部署saltstack

    原文发表于cu:2016-06-23 参考文档: Saltstack安装文档:https://repo.saltstack.com/#rhel saltstack的安装与简单配置,应用. 一.环境 S ...

  5. Codeforces 552 E. Two Teams

    E. Two Teams time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  6. mac安装php分词工具xunsearch出现找不到bio.h的解决办法

    下载xunsearch后安装出现如下错误,在xunsearch官方论坛未找到答案,此方案不仅用于参考解决安装xunsearch,其它编辑安装出现的问题同样可以参考 -n Checking scws . ...

  7. 智能客服 对话实现--python aiml包

    利用了python的aiml包进行应答 什么是AIML? AIML是Richard Wallace开发的. 他开发了一个叫A.L.I.C.E(Artificial Linguistics Intern ...

  8. 福大软工·第十一次作业-Alpha事后诸葛亮

    福大软工·第十一次作业-Alpha事后诸葛亮 组长博客链接 本次作业博客链接 项目Postmortem 模板 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...

  9. JScript脚本

    这个好强大啊 .fiddler2是部分是用这个语言开发的.

  10. springmvc 路由

    工作中MVC是较常使用的web框架,作为研发人员,也习惯了以编写Controller作为项目开始,写好了Controller和对应的方法,加上@RequestMapping注解,我们也就认为一切已经准 ...