【AC自动机】bzoj3172: [Tjoi2013]单词
fail图上后缀和需要注意一下
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
a
aa
aaa
Sample Output
3
1
题目分析
考虑暴力:将每一个单词作为文本串匹配,一旦遇到一个单词节点,就向上跳fail统计整条链上的所有单词的贡献。
注意到对于每一个匹配到的单词节点,有一个向上的后缀和的形式在这里。
那么从另一个方式考虑,对于每一个节点,计算有多少子节点会把它统计进答案里。
这样就可以用很自然的fail后缀和来处理这个问题了。
注意
要注意的是,trie图后缀和的统计顺序不能够简单地根据tot...1的顺序。
因为trie图是有分叉的,节点的标号与深度并无关系。
#include<bits/stdc++.h>
const int maxn = ;
const int maxNode = ; struct ACAutomaton
{
char s[maxn];
int vis[maxNode];
std::queue<int> q;
int stk[maxNode],cnt;
int fail[maxNode],f[maxNode][],size[maxNode],tot,n;
void insert(char *s, int t)
{
int u = , lens = strlen(s);
for (int i=; i<lens; i++)
{
int c = s[i]-'a';
if (!f[u][c]) f[u][c] = ++tot;
u = f[u][c], size[u]++;
}
vis[t] = u;
// vis[u]++;
}
24 void count() //其实这里写的冗长了一点
25 { //如果用手写的队列就不用再开一个数组了
26 for (int i=tot; i>1; i--)
27 size[fail[stk[i]]] += size[stk[i]];
28 }
void build()
{
for (int i=; i<=; i++) f[][i] = ;
q.push();
while (q.size())
{
int tt = q.front();
q.pop();
stk[++cnt] = tt;
for (int i=; i<=; i++)
if (f[tt][i])
fail[f[tt][i]] = f[fail[tt]][i], q.push(f[tt][i]);
else f[tt][i] = f[fail[tt]][i];
}
}
}f;
int n;
char s[]; int main()
{
scanf("%d",&n);
f.tot = ;
for (int i=; i<=n; i++)
scanf("%s",s), f.insert(s, i);
f.build(), f.count();
for (int i=; i<=n; i++) printf("%d\n",f.size[f.vis[i]]);
return ;
}
END
【AC自动机】bzoj3172: [Tjoi2013]单词的更多相关文章
- BZOJ3172 [Tjoi2013]单词 【AC自动机】
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 4293 Solved: 2083 [Submit][Stat ...
- bzoj千题计划315:bzoj3172: [Tjoi2013]单词(AC自动机)
https://www.lydsy.com/JudgeOnline/problem.php?id=3172 构建AC自动机 在fail树上,点i的子树大小 表示trie树上根节点到i构成的单词 是 多 ...
- [BZOJ3172 ][Tjoi2013]单词(AC自动机)
Description 不稳定的传送门 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次.单词个数<=200,单词总长度< ...
- BZOJ3172 [Tjoi2013]单词 字符串 SA ST表
原文链接http://www.cnblogs.com/zhouzhendong/p/9026543.html 题目传送门 - BZOJ3172 题意 输入$n(n\leq 200)$个字符串,保证长度 ...
- BZOJ3172: [Tjoi2013]单词
传送门 做了这么多题怎么还是无法很好的理解AC自动机呢..果然是个制杖 首先题意表述不是很清晰,这些所有的单词组成了那个文章,所以果断建个AC自动机,建的时候给每个点附加一个权值,建树是经过一次权值即 ...
- [Bzoj3172][Tjoi2013]单词(fail树)
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 4777 Solved: 2345[Submit][Status ...
- BZOJ3172[Tjoi2013]单词 题解
题目大意: 求一些字符串在一段文章中出现的次数. 思路: AC自动机的经典应用,建完自动机直接将队列里的元素调Fail指针记录即可. 代码: #include<cstdio> #inclu ...
- 【AC自动机】背单词
题意: 0 s v:添加价值为v的字符串s 1 t:查询t中含的s的权值和.(不停位置算多次) 思路: 在线AC自动机. 同学用过一个妙妙子的分块算法. 这里用二进制分组:通常用作把在线数据结构问题转 ...
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- bzoj3172: [Tjoi2013]单词 ac自动机
某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词 ...
随机推荐
- SQL SERVER Study
1. SQL SERVER Install 可以免费试用天.最新的是2014版本. 2. Attach, Detach 可以添加或去掉已有的数据库文件. 数据库文件的格式是: .md ...
- 2017"百度之星"程序设计大赛 - 初赛(A)小C的倍数问题
Problem Description 根据小学数学的知识,我们知道一个正整数x是3的倍数的条件是x每一位加起来的和是3的倍数.反之,如果一个数每一位加起来是3的倍数,则这个数肯定是3的倍数. 现在给 ...
- jQuery基础(1)
一.jQuery的介绍 1.为什么要使用jQuery? 在用js写代码时,会遇到一些问题,如下: 1)window.onload 事件有事件覆盖的问题,因此只能写一个事件: 2)代码容错性差: 3)浏 ...
- yii2.0下,JqPaginator与Pjax实现无刷新翻页
控制器部分 <?php namespace backend\controllers; use common\models\Common; use Yii; use yii\base\Contro ...
- MDX分页查询
WITH SET [e16a30d0-2174-4874-8dae-a5085a75a3e2] as NONEMPTY({[Measures].[终端销售数量], [Measures].[终端销售吊牌 ...
- idea报错:Error running $classname: Command line is too long. Shorten command line for $classname.
Command line is too long 打印的变量太长了,超过了限制,这都会报错...我只想知道idea基于什么原理会报这个错... 解决 1.按照提示修改该类的配置,选择jar manif ...
- datatables后台分页例子(可直接复制代码)
1.head表签引用 这两个文件即可 2.复制下面的代码到webform中的head标签中 <script> $(function () { //提示信息 var lang = { &qu ...
- 关于rabbitmq的消息路由的同步问题
http://www.cnblogs.com/me-sa/archive/2012/11/12/rabbitmq_ram_or_disk_node.html我是看了上面的博客明白了一些原理的,我之前一 ...
- AngularJS(四):控制器、事件
本文也同步发表在我的公众号“我的天空” 控制器 控制器可以说是AngularJS中最重要的部分了!之前的一些示例,除了第一讲的示例以外,我们对于AngularJS的使用都集中在HTML部分,其实Ang ...
- SQL基本语法总结
#创建数据库 DROP DATABASE IF EXISTS 数据库名; CREATE DATABASE 数据库名; #展示所有的数据库: SHOW DATABASES; #查看某个数据库的定义信息: ...