P3966 [TJOI2013]单词

题目链接:https://www.luogu.org/problemnew/show/P3966

题目描述

小张最近在忙毕设,所以一直在读论文。一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次。

输入输出格式

输入格式:

第一行一个整数N,表示有N个单词。接下来N行每行一个单词,每个单词都由小写字母(a-z)组成。(N≤200)

输出格式:

输出N个整数,第i行的数表示第i个单词在文章中出现了多少次。

输入输出样例

输入样例#1: 复制

3
a
aa
aaa
输出样例#1: 复制

6
3
1

说明

数据范围

30%的数据, 单词总长度不超过10^3

100%的数据,单词总长度不超过10^6

题解:

这个题其实问的是一个单词在其它单词中出现的次数,题意有点不清晰吧= =

一个单词若在其它单词中出现,那么其它单词的那一条链上,至少会有一个fail指针指向这个单词的末尾,表面这个单词为目前结点的后缀。

那么我们可以考虑将fail指针翻转,构成一个fail树,那么若统计A单词在其它单词中的出现次数,就直接看以A为根的子树一共有多少个结点就行了。

总体思路就是这样,由于单词可能会重合,并且某些单词可能为另一些单词的前缀,那么我们首先可以记录一共有多少个单词经过单词A的尾节点,假设记为v,那么说明现在他作为前缀的情况有v个了。

之后便根据后面的结点的fail指针从下往上进行更新,来统计作为后缀的情况(注意这里必须从下往上才能保证正确性,并且时间复杂度也比较低),具体的方法就是根据bfs序来进行更新,因为bfs序越大的,那么说明它的深度肯定在更下面,反正不会在上面= =

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+;
int n,tot;
char s[N];
int num[N],Q[N];
queue <int> q;
struct Aho_Corasick{
int Size;
int ch[N][];
int val[N];
int fail[N];
void init(){
Size=-;
newnode();
}
int newnode(){
memset(ch[++Size],,sizeof(ch[]));
fail[Size]=;
return Size;
}
void insert(char *s,int id){
int l=strlen(s);
int u=;
for(int i=;i<l;i++){
int idx=s[i]-'a';
if(!ch[u][idx]) ch[u][idx]=newnode();
u=ch[u][idx];
num[u]++;
}
val[id]=u;
}
void Getfail(){
while(!q.empty()) q.pop();
for(int i=;i<;i++){
if(ch[][i]) q.push(ch[][i]);
}
while(!q.empty()){
int cur=q.front();q.pop();
Q[++tot]=cur;
for(int i=;i<;i++){
if(ch[cur][i]){
fail[ch[cur][i]]=ch[fail[cur]][i];
q.push(ch[cur][i]);
}else{
ch[cur][i]=ch[fail[cur]][i];
}
}
}
}
}ac;
int main(){
cin>>n;
ac.init();
for(int i=;i<=n;i++){
scanf("%s",s);
ac.insert(s,i);
}
ac.Getfail();
for(int i=tot;i>=;i--) num[ac.fail[Q[i]]]+=num[Q[i]];
for(int i=;i<=n;i++){
printf("%d\n",num[ac.val[i]]);
}
return ;
}

洛谷P3966 [TJOI2013]单词(fail树性质)的更多相关文章

  1. 洛谷P3966 [TJOI2013]单词(AC自动机)

    题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...

  2. [洛谷P3966][TJOI2013]单词

    题目大意:有$n$个字符串,求每个字符串在所有字符串中出现的次数 题解:$AC$自动机,每个节点被经过时$sz$加一,每一个字符串出现次数为其$fail$树子树$sz$和 卡点:$AC$自动机根节点为 ...

  3. 洛谷P3966 [TJOI2013]单词(后缀自动机)

    传送门 统计单词出现次数……为啥大家都是写AC自动机的嘞……明明后缀自动机也能做的说…… 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...

  4. BZOJ3172 & 洛谷3966 [Tjoi2013]单词 【fail树】

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 4293  Solved: 2083 [Submit][Stat ...

  5. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  6. bzoj 3172: [Tjoi2013]单词 fail树

    题目大意: 一篇论文是由许多单词组成,现在想知道每个单词分别在论文中出现多少次. 题解: 我们首先考虑fail指针的含义 如果fail[x] = y,那么我们就知道y作为x的后缀在x中出现了一次 所以 ...

  7. P3966 [TJOI2013]单词

    P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...

  8. 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  9. 洛谷p3384【模板】树链剖分题解

    洛谷p3384 [模板]树链剖分错误记录 首先感谢\(lfd\)在课上调了出来\(Orz\) \(1\).以后少写全局变量 \(2\).线段树递归的时候最好把左右区间一起传 \(3\).写\(dfs\ ...

随机推荐

  1. java 实现redis缓存

    由于项目加载时请求数据量过大,造成页面加载很慢.采用redis作缓存,使二次访问时页面,直接取redis缓存. 1.redis连接参数 2.连接redis,设置库 3.配置文件开启缓存 4.mappe ...

  2. 网页性能管理详解:浅谈chrome-Timeline及window.requestAnimationFrame()方法

    你遇到过性能很差的网页吗? 这种网页响应非常缓慢,占用大量的CPU和内存,浏览起来常常有卡顿,页面的动画效果也不流畅. 你会有什么反应?我猜想,大多数用户会关闭这个页面,改为访问其他网站.作为一个开发 ...

  3. mapReduce入门教程

    什么是MapReduce MapReduce是Google提出的一个软件架构,用于大规模数据集(大于1TB)的并行运算.概念"Map(映射)"和"Reduce(归纳)&q ...

  4. 剑指offer-二叉树搜索树与双向链表25

    题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. class Solution: def Convert(self, pRo ...

  5. 2018(容斥定理 HDU6286)

    2018 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  6. 编译安装hadoop2.6.3

    一.安装环境 1.1  JAVA  安装java1.7 下载jdk1.7: [root@node1~]# wget http://download.oracle.com/otn-pub/java/jd ...

  7. Fluent Python: Classmethod vs Staticmethod

    Fluent Python一书9.4节比较了 Classmethod 和 Staticmethod 两个装饰器的区别: 给出的结论是一个非常有用(Classmethod), 一个不太有用(Static ...

  8. Thunder团队第二周 - Scrum会议4

    Scrum会议4 小组名称:Thunder 项目名称:爱阅app Scrum Master:邹双黛 工作照片: 宋雨同学在拍照,所以不再照片中. 参会成员: 王航:http://www.cnblogs ...

  9. Android开发随笔5

    昨天: 对界面的进一步设计补充 可以在界面之间的跳转 研究了对图标等的操作 今天: 实现对库的相关操作 学习视视频内容‘ 复习java的一些知识.

  10. Android 平台 HTTP网速测试 案例 API 分析

    作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/25996817 工信部规定的网速测试标准 : 除普通网页测速 ...