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 ...
随机推荐
- python正则表达式-re模块的爱恨情仇
利用python的re模块,使用正则表达式对字符串进行处理 # 编辑者:闫龙 import re restr = "abccgccc123def456ghi789jgkl186000&quo ...
- vue组件之间传值方式解析
vue组件之间传值方式解析一.父组件传到子组件 1.父组件parent代码如下: <template> <div class="parent"> <h ...
- nginx+tomat https ssl 部署 完美解决方案
关于nginx+tomcat https的部署之前网上一直有2种说法: 1.nginx和tomcat都要部署ssl证书 2.nginx部署ssl证书,tomcat增加ssl支持 在实际的部署过程中ng ...
- CentOS_5.5_安装GCC编译LiME
1 概述 近期遇到个使用CentOS 5.5的系统,生产环境没有GCC.GDB.要对这台机器抓取关键内存回去用volatility分析. 思路1:使用工具Dump某个进程的内存.使用cat /proc ...
- C#匿名函数与Lambda表达式
Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数.在C#中的Linq中的大部分就是由扩展方法 ...
- MongoDB中多表关联查询(
1.使用aggregate 查看表数据 db.getCollection('reports').aggregate([ { $lookup: { from: "process", ...
- Codeforces 963A Alternating Sum(等比数列求和+逆元+快速幂)
题目链接:http://codeforces.com/problemset/problem/963/A 题目大意:就是给了你n,a,b和一段长度为k的只有'+'和‘-’字符串,保证n+1被k整除,让你 ...
- Linux 命令find、grep
本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: find命令 find命令的一般形式 find命令的常用选项及实例 find与xar ...
- CVE-2010-0248
[CNNVD]Microsoft Internet Explorer 多个远程代码执行漏洞(CNNVD-201001-237) Microsoft Internet Explorer 6, 6 SP1 ...
- MIT6.006Lec01:Python实现
MIT6.006是Algo Intro这门课,据说语言使用python Lec01是讲peak finding,也就是峰值点 具体为: 一维情况下一个数组中a[i]>a[i-1]且a[i]> ...