[TJOI2013]单词 AC自动机
题面:
题解:
很久之前做的题了,只不过之前一直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自动机的更多相关文章
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- 【BZOJ3172】[Tjoi2013]单词 AC自动机
[BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- 洛谷P3966 [TJOI2013]单词(AC自动机)
题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...
- [TJOI2013]单词 AC 自动机
题目描述: 小张最近在忙毕设,所以一直在读论文. 一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 题解: AC 自动机裸题,将所有字符串读入 ...
- 【BZOJ 3172】[Tjoi2013]单词 AC自动机
关于AC自动机:一个在kmp与Trie的基础上建立的数据结构,关键在于Trie树结构与fail指针,他们各有各的应用.在AC自动机里最典型的就是多串匹配,原本效率为O(n*l+n*l+m*l),(n是 ...
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树
题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...
- bzoj3172: [Tjoi2013]单词 ac自动机
某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词 ...
随机推荐
- tidb测试环境安装,离线部署
1.环境以及规划 机器:centos7.5 ; 文件系统为ext4:内存16g:cpu8核,共三个节点: ip hostname roles --- tidb tipd tikv --- tidb t ...
- 电信NB-IOT的温湿度采集器开发记录
1. 首先打开浏览器,登录电信商用服务器,上传profile文件 2. 上传编解码插件在,注意的是,上传编解码插件是电信测试用服务器平台(不同的网址),反正不明白电信搞啥幺蛾子,得两个地方去上传 3. ...
- Android开发笔记——图片缓存、手势及OOM分析
把图片缓存.手势及OOM三个主题放在一起,是因为在Android应用开发过程中,这三个问题经常是联系在一起的.首先,预览大图需要支持手势缩放,旋转,平移等操作:其次,图片在本地需要进行缓存,避免频繁访 ...
- javaweb(三十九)——数据库连接池
一.应用程序直接获取数据库连接的缺点 用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长.假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大 ...
- javaweb(十五)——JSP基础语法
任何语言都有自己的语法,JAVA中有,JSP虽然是在JAVA上的一种应用,但是依然有其自己扩充的语法,而且在JSP中,所有的JAVA语句都可以使用. 一.JSP模版元素 JSP页面中的HTML内容称之 ...
- [ASP.NET Core] 建置x86版本 (workaround)
前言 本篇文章介绍如何建置ASP.NET Core项目的x86版本输出(workaround),为自己留个纪录也希望能帮助到有需要的开发人员. ASP.NET Core官网 步骤 首先到微软官网的「. ...
- 令自己的本地ip可以被外网访问
https://www.ngrok.cc/_book/general/open.html
- Egret入门(二)--windows下环境搭建
准备材料 安装Node.js TypeScript编辑器 HTTP服务器(可选) Chorme(可选) Egret 安装Node.js 打开www.nodejs.org 下载安装(全部next,全默认 ...
- Python基础灬函数(定义,参数)
函数 函数定义 # 定义一个计算绝对值的函数 def cal_abs(x): if x >= 0: return x else: return -x # 调用函数 print('-1的绝对值是: ...
- 第五章—if语句
5-1 条件测试 :编写一系列条件测试:将每个测试以及你对其结果的预测和实际结果都打印出来.你编写的代码应类似于下面这样: car = 'subaru' print("Is car == ' ...