BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树
题目链接:【http://www.lydsy.com/JudgeOnline/problem.php?id=3172】
题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号隔开。
题解:时间很坑啊,朴素的做法是,先在AC自动机上插入单词,并记录下每个单词,然后用每个单词去维护答案。但是这样做时间空间都不允许,只有在插入的时候维护答案。过程是这样的,在插入的时候,每经过一个点,该节点的值加一,同时记录单词末尾的位置,然后在求玩Fail的时候,倒着走回去就可以了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2024 * 1024 + 15;
char tmp[maxn];
struct Aho_C
{
int Next[maxn][26], Fail[maxn], pos[maxn], cnt[maxn];
int que[maxn], st, ed;
int root, sz;
int newnode()
{
for(int i = 0; i < 26; i++) Next[sz][i] = 0;
cnt[sz] = 0;
sz++;
return sz - 1 ;
}
void init()
{
sz = 0;
root = newnode();
}
void Insert(char buf[], int id)
{
int len = strlen(buf);
int now = root;
for(int i = 0; i < len; i++)
{
if(!Next[now][buf[i] - 'a'])
Next[now][buf[i] - 'a'] = newnode();
now = Next[now][buf[i] - 'a'];
cnt[now]++;
}
pos[id] = now;
}
void getFail()
{
st = ed = 1;
for(int i = 0; i < 26; i++)
if(Next[root][i])
que[ed++] = Next[root][i];
while(st != ed)
{
int u = que[st++];
for(int i = 0; i < 26; i++)
{
int &v = Next[u][i];
if(!v)
{
v = Next[Fail[u]][i];
continue;
}
Fail[v] = Next[Fail[u]][i];
que[ed++] = v;
}
}
for(int i = ed - 1; i >= 1; i--) cnt[Fail[que[i]]] += cnt[que[i]];
}
} ac;
int main()
{
int N;
scanf("%d", &N);
ac.init();
for(int i = 1; i <= N; i++)
{
scanf("%s", tmp);
ac.Insert(tmp, i);
}
ac.getFail();
for(int i = 1; i <= N; i++) printf("%d\n", ac.cnt[ac.pos[i]]);
return 0;
}
BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树的更多相关文章
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树
Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- BZOJ 3172 [Tjoi2013]单词 AC自己主动机(fail树)
题意:链接 方法:AC自己主动机与fail树性质 解析:复习AC自己主动机的第一道题?(真正的第一题明明是又一次写了遍hdu2222! ) 这题说实话第一眼看上去就是个sb题,仅仅要建出来自己主动机. ...
- BZOJ2905: 背单词 AC自动机+fail树+线段树
$zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...
- bzoj 3172 [Tjoi2013]单词(fail树,DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3172 [题意] 题目的意思是这样的,给若干个单词,求每个单词在这一堆单词中的出现次数. ...
- 【学习笔记】ac自动机&fail树
定义 解决文本串和多个模式串匹配的问题: 本质是由多个模式串形成的一个字典树,由tie的意义知道:trie上的每一个节点都是一个模式串的前缀: 在trie上加入fail边,一个节点fail边指向这个节 ...
- BZOJ 3172([Tjoi2013]单词-后缀数组第一题+RMQ)
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 268 Solved: 145 [ Submit][ St ...
随机推荐
- Mysql 关闭自动commit
更多内容推荐微信公众号,欢迎关注: 1. 会话级关闭自动提交 mysql> set autocommit=off; Query OK, 0 rows affected (0.00 sec) my ...
- awk的常用内置函数的使用【转】
手把手教你在linux下熟悉使用awk的指令结构 (15) 大家好,今天和大家说一下awk吧.反正正则 早晚也要和大家说,不如一点一点和大家先交代清楚了,省得以后和大家说的时候,大家有懵的感觉... ...
- plupload 上传组件的使用
在这之前在感谢园子好多大牛的文章,在这里就不列出来了. 进入正题. svn检索https://github.com/moxiecode/plupload 获取到代码,这篇文章使用的是v2.1.8 主要 ...
- 磁盘性能分析之iotop
一.安装. yum install iotop [root@localhost tmp]# iotop -o iotop命令的键盘快捷键: 1.左右箭头改变排序方式,默认是按IO排序 2.r键是反向排 ...
- Python开发环境(1):Eclipse+PyDev插件
电脑:小米笔记本电脑Pro 15.6寸(i5-8250U),操作系统:Windows 10,JDK版本:1.8.0_152(环境变量已配置) Step 1.下载Eclipse 根据我的CPU型号,选择 ...
- 打开mvc项目无法运行,报"Unable to launch the IIS Express Web server"
今天遇到一个问题,打开asp.net mvc 项目,右击浏览器运行,无法运行... 提示下面错误, 解决方案: 删除项目文件夹下的 .vs 文件夹,然后重新打开项目运行即可 参考:http://www ...
- FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑
FFmpeg_Tutorial FFmpeg工具和sdk库的使用demo 一.使用FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑 1.基本介绍 对于每一个从事音视频技术开发的工程师,想必没 ...
- P1183 多边形的面积
一道睡论数论题 其实是AC300祭才做的水题 题意: 很直白的的题意啊,就是求任意一个多边形的面积 所以我们来安利一下一个求多边形面积的数学通式: 给定多边形的顶点坐标(有序),让你来求这个多边形的面 ...
- HDU 5115 Dire Wolf (区间DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115 题目大意:有一些狼,从左到右排列,每只狼有一个伤害A,还有一个伤害B.杀死一只狼的时候,会受到这 ...
- javaweb作业二
作业:1.书写servlet的类架构及重要方法.(ServletConfig,Servlet)<---GenericServlet(getInitParameter(String str);in ...