【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】
P3966 [TJOI2013]单词
题目描述
小张最近在忙毕设,所以一直在读论文。一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次。
输入输出格式
输入格式:
第一行一个整数N,表示有N个单词。接下来N行每行一个单词,每个单词都由小写字母(a-z)组成。(N≤200)
输出格式:
输出N个整数,第i行的数表示第i个单词在文章中出现了多少次。
输入输出样例
说明
数据范围
30%的数据, 单词总长度不超过10^3
100%的数据,单词总长度不超过10^6
Solution
解法也是挺简单的,首先肯定是建出ac自动机。
然后我们考虑fail指针的含义,$fail[u]$到根节点是$u$到根节点串的后缀,也就是以$fail[u]$为结尾的串在$u$中出现了$cnt[u]$次...
所有的fail都是这样的,所以反向建fail指针变成fail树,统计子树和更新$cnt$,$cnt[u]$就是每个$u$为结尾的串出现的次数了。
在bfs的时候存下遍历顺序,最后倒着更新就可以了。
Code
#include<bits/stdc++.h>
#define LL long long
using namespace std; string s[];
int n;
LL ans[], cnt[];
int son[][], fail[], tail, las[];
void insert(string a, int opt) {
int len = a.length();
int nd = ;
for(int i = ; i < len; i ++) {
int t = a[i] - 'a' + ;
if(!son[nd][t]) son[nd][t] = ++ tail;
nd = son[nd][t];
cnt[nd] ++;
}
las[opt] = nd;
} int Q[], t;
void get_fail() {
queue < int > q;
Q[++t] = ;
for(int i = ; i <= ; i ++) if(son[][i]) fail[son[][i]] = , q.push(son[][i]);
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = ; i <= ; i ++) {
if(son[u][i]) fail[son[u][i]] = son[fail[u]][i], q.push(son[u][i]), Q[++t] = son[u][i];
else son[u][i] = son[fail[u]][i];
}
}
} int main() {
scanf("%d", &n);
for(int i = ; i <= n; i ++) {
cin >> s[i];
insert(s[i], i);
}
get_fail();
for(int i = t; i; i --) {
int now = Q[i];
cnt[fail[now]] += cnt[now];
}
for(int i = ; i <= n; i ++)
printf("%lld\n", cnt[las[i]]);
return ;
}
【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】的更多相关文章
- 洛谷P3966 [TJOI2013]单词(AC自动机)
题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- BZOJ3172[Tjoi2013]单词——AC自动机(fail树)
题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...
- 洛谷2414(构建ac自动机fail树dfs序后遍历Trie树维护bit及询问答案)
要点 这是一道蔡队题,看我标题行事 任意询问y串上有多少个x串,暴力找每个节点是不是结尾肯定是炸的,考虑本质:如果某节点是x的结尾,根据ac自动机的性质,x一定是此(子)串后缀.又有每个Trie节点的 ...
- BZOJ 3172 [Tjoi2013]单词 AC自动机Fail树
题目链接:[http://www.lydsy.com/JudgeOnline/problem.php?id=3172] 题意:给出一个文章的所有单词,然后找出每个单词在文章中出现的次数,单词用标点符号 ...
- BZOJ3172 & 洛谷3966 [Tjoi2013]单词 【fail树】
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 4293 Solved: 2083 [Submit][Stat ...
- BZOJ2905: 背单词 AC自动机+fail树+线段树
$zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...
- BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树
Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...
- 【学习笔记】ac自动机&fail树
定义 解决文本串和多个模式串匹配的问题: 本质是由多个模式串形成的一个字典树,由tie的意义知道:trie上的每一个节点都是一个模式串的前缀: 在trie上加入fail边,一个节点fail边指向这个节 ...
- 洛谷P3966 [TJOI2013]单词(fail树性质)
P3966 [TJOI2013]单词 题目链接:https://www.luogu.org/problemnew/show/P3966 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...
随机推荐
- 洛谷 P4592: bzoj 5338: [TJOI2018]异或
题目传送门:洛谷P4592. 题意简述: 题面说的很清楚了. 题解: 发现没有修改很快乐.再看异或最大值操作,很容易想到可持久化 01trie. 这里要把 01trie 搬到树上,有点难受. 树剖太捞 ...
- asp.net 伪静态实现(UrlRewritingNet)
UrlRewritingNet.UrlRewriter源码地址 https://github.com/aspnetde/UrlRewritingNet部署步骤: 步骤一: <!--只允许存在一个 ...
- Flask:静态文件&模板(0.1)
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 前面看了Flask的Quickstart文档,可是,一直没有练习里面的内容,这不,刚刚练习完毕,来写篇博文记录一下! ...
- Web Api - HttpMessageHandler 学习
参考: 1.http://www.cnblogs.com/chenboyi081/p/4995252.html 2.http://www.cnblogs.com/r01cn/archive/2012/ ...
- 密码记录工具keepass保存密码
https://www.cnblogs.com/wicub/p/5753005.html
- [转] Cacti+Nagios监控平台完美整合
Cacti+Nagios监控平台完美整合 http://os.51cto.com/art/201411/458006.htm 整合nagios+cacti+微信.飞信实现网络监控报警 http://b ...
- 题解 UVA10048 【Audiophobia】
这是一道很神奇的题 什么都不卡,就卡c++11(所以评测时要换成c++). 怎么说呐,其实就是跑一个弗洛依德,求图上两点间最大权值最小的路径,输出最大权值最小. P.S.本题n很小,直接floyd变形 ...
- 云计算IaaS浅谈
(本篇文章仅仅是整理文档资料时,发现的一篇课程报告,感觉还挺有参考意义的) 最近几年云计算一直是IT业的热点,一股炽热的云计算浪潮席卷了世界,全世界都在讲云计算,都在搞云计算.虽然最初是由谷歌公司提出 ...
- POJ 2195 Going Home(KM算法模板)
题目链接:http://poj.org/problem?id=2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致. man每移动一格需花费$1 ...
- vue组件中的轮播实现
一.直接上代码 <template> <el-row class="Slide"> <el-row class="title"&g ...