fail图上后缀和需要注意一下

Description

某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。

Input

第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6

Output

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

Sample Input

3
a
aa
aaa

Sample Output

6
3
1

题目分析

考虑暴力:将每一个单词作为文本串匹配,一旦遇到一个单词节点,就向上跳fail统计整条链上的所有单词的贡献。

注意到对于每一个匹配到的单词节点,有一个向上的后缀和的形式在这里。

那么从另一个方式考虑,对于每一个节点,计算有多少子节点会把它统计进答案里。

这样就可以用很自然的fail后缀和来处理这个问题了。

注意

要注意的是,trie图后缀和的统计顺序不能够简单地根据tot...1的顺序。

因为trie图是有分叉的,节点的标号与深度并无关系。

 #include<bits/stdc++.h>
const int maxn = ;
const int maxNode = ; struct ACAutomaton
{
char s[maxn];
int vis[maxNode];
std::queue<int> q;
int stk[maxNode],cnt;
int fail[maxNode],f[maxNode][],size[maxNode],tot,n;
void insert(char *s, int t)
{
int u = , lens = strlen(s);
for (int i=; i<lens; i++)
{
int c = s[i]-'a';
if (!f[u][c]) f[u][c] = ++tot;
u = f[u][c], size[u]++;
}
vis[t] = u;
// vis[u]++;
}
24 void count()      //其实这里写的冗长了一点
25 {             //如果用手写的队列就不用再开一个数组了
26 for (int i=tot; i>1; i--)
27 size[fail[stk[i]]] += size[stk[i]];
28 }
void build()
{
for (int i=; i<=; i++) f[][i] = ;
q.push();
while (q.size())
{
int tt = q.front();
q.pop();
stk[++cnt] = tt;
for (int i=; i<=; i++)
if (f[tt][i])
fail[f[tt][i]] = f[fail[tt]][i], q.push(f[tt][i]);
else f[tt][i] = f[fail[tt]][i];
}
}
}f;
int n;
char s[]; int main()
{
scanf("%d",&n);
f.tot = ;
for (int i=; i<=n; i++)
scanf("%s",s), f.insert(s, i);
f.build(), f.count();
for (int i=; i<=n; i++) printf("%d\n",f.size[f.vis[i]]);
return ;
}

END

【AC自动机】bzoj3172: [Tjoi2013]单词的更多相关文章

  1. BZOJ3172 [Tjoi2013]单词 【AC自动机】

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

  2. bzoj千题计划315:bzoj3172: [Tjoi2013]单词(AC自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3172 构建AC自动机 在fail树上,点i的子树大小 表示trie树上根节点到i构成的单词 是 多 ...

  3. [BZOJ3172 ][Tjoi2013]单词(AC自动机)

    Description 不稳定的传送门 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次.单词个数<=200,单词总长度< ...

  4. BZOJ3172 [Tjoi2013]单词 字符串 SA ST表

    原文链接http://www.cnblogs.com/zhouzhendong/p/9026543.html 题目传送门 - BZOJ3172 题意 输入$n(n\leq 200)$个字符串,保证长度 ...

  5. BZOJ3172: [Tjoi2013]单词

    传送门 做了这么多题怎么还是无法很好的理解AC自动机呢..果然是个制杖 首先题意表述不是很清晰,这些所有的单词组成了那个文章,所以果断建个AC自动机,建的时候给每个点附加一个权值,建树是经过一次权值即 ...

  6. [Bzoj3172][Tjoi2013]单词(fail树)

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 4777  Solved: 2345[Submit][Status ...

  7. BZOJ3172[Tjoi2013]单词 题解

    题目大意: 求一些字符串在一段文章中出现的次数. 思路: AC自动机的经典应用,建完自动机直接将队列里的元素调Fail指针记录即可. 代码: #include<cstdio> #inclu ...

  8. 【AC自动机】背单词

    题意: 0 s v:添加价值为v的字符串s 1 t:查询t中含的s的权值和.(不停位置算多次) 思路: 在线AC自动机. 同学用过一个妙妙子的分块算法. 这里用二进制分组:通常用作把在线数据结构问题转 ...

  9. BZOJ3172[Tjoi2013]单词——AC自动机(fail树)

    题目描述 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. 输入 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个 ...

  10. bzoj3172: [Tjoi2013]单词 ac自动机

    某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input 第一个一个整数N,表示有多少个单词,接下来N行每行一个单词.每个单词 ...

随机推荐

  1. 笔记-JavaWeb学习之旅15

    Filter:过滤器 概念:当访问服务器的资源是,过滤器可以将请求拦截下来,完成一些特殊的功能 快速入门: 步骤: 定义一个类,实现接口Filter 复写方法 配置拦截路径 package com.d ...

  2. [软件工程基础]Alpha 软件测试报告

    PhyLab Alpha 测试报告 测试中发现的bug Alpha版本限制与问题 由于接手时数据库已经丢失,这一版本主要修复了大部分数据库,使得网站得以运行. 相比接手时网站的状况,有以下改进: 恢复 ...

  3. Linux中/etc/passwd 和 /etc/shadows 详解

    linux操作系统上的用户如果需要登录主机,当其输入用户名和密码之后: 首先在/etc/passwd文件中查找是否有你的账号,如果没有无法登录,如果有的话将该用户的UID和GID读出来,此外将此用户的 ...

  4. python大战机器学习——人工神经网络

    人工神经网络是有一系列简单的单元相互紧密联系构成的,每个单元有一定数量的实数输入和唯一的实数输出.神经网络的一个重要的用途就是接受和处理传感器产生的复杂的输入并进行自适应性的学习,是一种模式匹配算法, ...

  5. namedJDBC查询

    import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.spring ...

  6. AnyCAD OpenSource 版本下载和编译

    下载: SVN下载地址:https://anycad.svn.codeplex.com/svn 或者直接下载:http://anycad.codeplex.com/SourceControl/late ...

  7. Git入门学习总结

    用了两天时间看完廖雪峰老师的git教程(http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b0 ...

  8. JS根据选择的日期计算年龄

    本例中用的是easyUI的datebox $('#cal_birthday').datebox({ onSelect: function(date){ //根据选则的日期计算年龄 //alert(da ...

  9. .Net平台互操作技术:02. 技术介绍

    上一篇文章简单介绍了.Net平台互操作技术的面临的主要问题,以及主要的解决方案.本文将重点介绍使用相对较多的P/Invoke技术的实现:C#通过P/Invoke调用Native C++ Dll技术.C ...

  10. object flash

    <!-- html插入flash --> <object type="application/x-shockwave-flash" width="100 ...