【洛谷】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 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...
随机推荐
- RW RO ZI ROM keil中的含义
编译的一个ARM的程序,会得到这样的信息: ============================================================================== ...
- 【Git】Git与GitHub 入门【转】
转自:http://www.cnblogs.com/lcw/p/3394545.html GitHub GitHub是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公 ...
- Nginx常见错误与问题之解决方法技术指南
Nginx常见错误与问题之解决方法技术指南. 安装环境: 系统环境:redhat enterprise 6.5 64bit 1.Nginx 常见启动错误 有的时候初次安装nginx的时候会报这样的 ...
- 双机/RAC/Dataguard的区别【转】
本文转自 双机/RAC/Dataguard的区别-jasoname-ITPUB博客 http://blog.itpub.net/22741583/viewspace-684261/ Data Guar ...
- C# 浅谈 接口(Interface)的作用
继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基类无法实现的 1.接口用于描述一组类的公共方法/公共属性. 它不实现任何的方法 ...
- http://code52.org/DownmarkerWPF/
http://code52.org/DownmarkerWPF/ http://kb.cnblogs.com/page/132209/
- /touch滑屏事件
//touch滑屏事件 var windowHeight = $(window).height(), $body = $("body"); $body.cs ...
- 题解 UVA10048 【Audiophobia】
这是一道很神奇的题 什么都不卡,就卡c++11(所以评测时要换成c++). 怎么说呐,其实就是跑一个弗洛依德,求图上两点间最大权值最小的路径,输出最大权值最小. P.S.本题n很小,直接floyd变形 ...
- MySQL学习笔记:计算机服务中找不到MySQL服务
不知道什么原因,连接了远程服务器之后,本地服务就连接不上. 经排查,发现服务中的MySQL服务居然不见,一番搜索之后,在CMD中进入到MySQL安装目录的bin下执行以下语句: mysqld.exe ...
- peda的官方文档说明
peda在github上的官方文档,摘抄过来,方便查阅. 安装 git clone https://github.com/longld/peda.git ~/peda echo "sourc ...