【BZOJ3172】单词(AC自动机)

题面

Description

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

Input

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

Output

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

Sample Input

3

a

aa

aaa

Sample Output

6

3

1

题解

yyb因为调这道题而死亡

在重复一下题目的意思把。。。

看不见文章对不读,,

那是因为文章就是所有单词组成的

然后你就可以yy所有单词中间有一个空格之类的东西

很明显的AC自动机,

然后,我们

每次把每个单词带进去匹配一下

暴跳fail指针

美滋滋的收获90分

0分是空间玩炸了。。。

暴跳fail指针是可以被卡炸的。。。

所以,我们就不暴跳了呀

每次要跳的时候就在这个点这里打一个标记

所有标记打完之后

我们就从底下往上一层层跳(记一下bfs序倒着跳)

每次就只跳一层,然后标记丢到上面去

这样就可以一起跳啦

然后美滋滋的 AC啦

对了,

这题还有一点

就是会有重复的单词。。。

所以要记录一下每个单词和哪个单词是一样的(不是并查集)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 1100000
struct Node
{
int vis[26];
int fail,ff;
int id,sum;
}t[MAX];
int tot,lid[500];
int ans[500];
int n,q[MAX],tp;
char ch[MAX],ss[MAX];
void Insert(int id,char *s)
{
int gg=strlen(s);
int now=0;
for(int i=0;i<gg;++i)
{
if(!t[now].vis[s[i]-'a'])
t[now].vis[s[i]-'a']=++tot;
t[t[now].vis[s[i]-'a']].ff=now;
now=t[now].vis[s[i]-'a'];
}
if(!t[now].id)t[now].id=id,lid[id]=id;
else lid[id]=t[now].id;
}
queue<int> Q;
void GetFail()
{
for(int i=0;i<26;++i)
if(t[0].vis[i])
Q.push(q[++tp]=t[0].vis[i]);
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=0;i<26;++i)
{
if(t[u].vis[i])
t[t[u].vis[i]].fail=t[t[u].fail].vis[i],Q.push(q[++tp]=t[u].vis[i]);
else
t[u].vis[i]=t[t[u].fail].vis[i];
}
}
}
int l=0;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%s",ch);
Insert(i,ch);
int len=strlen(ch);
for(int j=0;j<len;++j)
ss[l++]=ch[j];
ss[l++]='#';
}
GetFail();
int now=0;
for(int j=0;j<l;++j)
{
if(ss[j]=='#')now=0;
else now=t[now].vis[ss[j]-'a'];
t[now].sum++;
}
for(int i=tp;i;i--)
{
ans[t[q[i]].id]+=t[q[i]].sum;
t[t[q[i]].fail].sum+=t[q[i]].sum;
}
for(int i=1;i<=n;++i)printf("%d\n",ans[lid[i]]);
return 0;
}

【BZOJ3172】单词(AC自动机)的更多相关文章

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

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

  2. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

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

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

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

  4. BZOJ2905: 背单词 AC自动机+fail树+线段树

    $zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...

  5. [TJOI2013]单词 AC自动机

    题面: 洛谷 题解: 很久之前做的题了,只不过之前一直90....最近才发现是哪里写错了. 我们对字符集建AC自动机. 首先考虑一个暴力的做法,把文章当做一个长串,直接在自动机上跳,但是我们会发现,这 ...

  6. bzoj 3172: [Tjoi2013]单词 AC自动机

    3172: [Tjoi2013]单词 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  7. [TJOI2013]单词 AC 自动机

    题目描述: 小张最近在忙毕设,所以一直在读论文. 一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 题解: AC 自动机裸题,将所有字符串读入 ...

  8. BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树

    Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...

  9. toj 4063 单词(AC自动机)

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

  10. bzoj 3172 单词 ac自动机|后缀数组

    题目大意: 给定n个字符串连成了一篇文章,问每个字符串在这篇文章中出现的次数,可重复覆盖 这里ac自动机和后缀数组都可以做 当然后缀数组很容易就解决,但是相对时间消耗高 这里就只讲ac自动机了 将每个 ...

随机推荐

  1. 购物车【JavaWeb小项目、简单版】

    前言 为了巩固MVC的开发模式,下面就写一个购物车的小案例.. ①构建开发环境 导入需要用到的开发包 建立程序开发包 ②设计实体 书籍实体 public class Book { private St ...

  2. ftp服务器的简单配置使用

    yum install -y vsftpd systemctl start vsftpd   cd /var/ftp/pub/   mkdir 111   touch weifeng.txt     ...

  3. Scrapy-简单介绍

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为了 页面抓取 (更确切来说, 网络抓取 )所设计的, ...

  4. [bzoj2286][Sdoi 2011]消耗战

    [bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...

  5. 让互联网更快:新一代QUIC协议在腾讯的技术实践分享

    本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...

  6. SpringMvc Ant通配符的使用

    @RequestMapping使用通配符来对地址进行映射 Ant 的3风格 – ? 匹配文件名中的一个字符 – *  匹配文件名中的任意字符 – ** ** 匹配多重路径 例如:RequestMapp ...

  7. java中try catch块的使用

    对于关流操作的时候,最好采用如下语句块: InputStream in=......; try{ try{ //some statemenet }finally{ //close stream in. ...

  8. Linux定时任务深入学习

    为当前用户创建cron服务 1.  键入 crontab  -e 编辑crontab服务文件 例如 文件内容如下: */2 * * * * /bin/sh /home/admin/jiaoben/bu ...

  9. Java语言的分支

    JavaSE:(标准版)是java基础,早期叫j2se,2005改名叫JavaSE(必须). JavaME:(移动版)适合移动端的开发.j2me,2005改名叫java ME(不学) JavaEE:( ...

  10. EmguCV 绘画图形

    1.Image类中绘图常用函数列表 实践验证 ///初始化图片 private void Form1_Load(object sender, EventArgs e) { oldpic = new E ...