P3966 [TJOI2013]单词
P3966 [TJOI2013]单词
题目描述
小张最近在忙毕设,所以一直在读论文。一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次。
输入输出格式
输入格式:
第一行一个整数N,表示有N个单词。接下来N行每行一个单词,每个单词都由小写字母(a-z)组成。(N≤200)
输出格式:
输出N个整数,第i行的数表示第i个单词在文章中出现了多少次。
输入输出样例
3
a
aa
aaa
6
3
1
说明
数据范围
30%的数据, 单词总长度不超过10^3
100%的数据,单词总长度不超过10^6
看上去题目貌似很简单,不就是把trie树一建然后对每个单词跑一遍AC自动机吗?然而这样会被卡死,考虑如何来优化,由于题目中说每一个单词会多次出现,那么我们就可以统计一下每个单词出现的次数,把这个出现次数看做这个单词的权值,然后在跑AC自动机时直接把这个权值加入到答案中,那么我们如何处理重复出现的单词并统计次数呢?其实我们在trie树上就可以搞定,如果两个单词相同,那么他们在trie树上的结束节点一定相同,这样就可以进行统计了。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#define maxn 1050005
using namespace std; inline int read()
{
char c=getchar();
int res=,x=;
while(c<''||c>'')
{
if(c=='-')
x=-;
c=getchar();
}
while(c>=''&&c<='')
{
res=res*+(c-'');
c=getchar();
}
return res*x;
} int n,tot=;
int tree[maxn][],nt[maxn],bo[maxn],ed[maxn],f[maxn],t[maxn];
char a[][maxn];
queue<int>q; void trie(char *s,int num)
{
int len=strlen(s),u=;
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
if(!tree[u][c])
{
tree[u][c]=++tot;
}
u=tree[u][c];
}
if(bo[u])
t[num]=;//t数组表示这个单词之前是否出现过
bo[u]++;
ed[num]=u;
} void bfs()
{
for(register int i=;i<;i++)
{
tree[][i]=;
}
nt[]=;q.push();
while(q.size())
{
int u=q.front();q.pop();
for(register int i=;i<;i++)
{
if(!tree[u][i])
tree[u][i]=tree[nt[u]][i];
else
{
int v=tree[u][i];
q.push(v);
nt[v]=tree[nt[u]][i];
}
}
}
} void find(char *s,int num)
{
int len=strlen(s),u=,k,ans=bo[ed[num]];//ans表示这个单词出现的次数
for(register int i=;i<len;i++)
{
int c=s[i]-'a';
k=tree[u][c];
while(k>)
{
if(bo[k])
f[k]+=ans;
k=nt[k];
}
u=tree[u][c];
}
} int main()
{
n=read();
for(register int i=;i<=n;i++)
{
scanf("%s",a[i]);
trie(a[i],i);
}
bfs();
for(register int i=;i<=n;i++)
{
if(!t[i])//这里我们只需要将每个不重复出现的单词跑一边AC自动机
find(a[i],i);
}
for(register int i=;i<=n;i++)
{
printf("%d\n",f[ed[i]]);
}
return ;
}
P3966 [TJOI2013]单词的更多相关文章
- 洛谷P3966 [TJOI2013]单词(fail树性质)
P3966 [TJOI2013]单词 题目链接:https://www.luogu.org/problemnew/show/P3966 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...
- 洛谷P3966 [TJOI2013]单词(AC自动机)
题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...
- 洛谷P3966 [TJOI2013]单词(后缀自动机)
传送门 统计单词出现次数……为啥大家都是写AC自动机的嘞……明明后缀自动机也能做的说…… 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...
- Luogu P3966 [TJOI2013]单词
题目链接 \(Click\) \(Here\) 本题\(AC\)自动机写法的正解之一是\(Fail\)树上跑\(DP\). \(AC\)自动机是\(Trie\)树和\(Fail\)树共存的结构,前者可 ...
- [洛谷P3966][TJOI2013]单词
题目大意:有$n$个字符串,求每个字符串在所有字符串中出现的次数 题解:$AC$自动机,每个节点被经过时$sz$加一,每一个字符串出现次数为其$fail$树子树$sz$和 卡点:$AC$自动机根节点为 ...
- 【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】
P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
- 【BZOJ3172】[Tjoi2013]单词 AC自动机
[BZOJ3172][Tjoi2013]单词 Description 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次. Input ...
- 3172: [Tjoi2013]单词
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3246 Solved: 1565[Submit][Status ...
随机推荐
- 数据分析之Numpy
Numpy numpy.array:将数组转换成向量 numpy.array([,,,]) 转化成1维向量 numpy.array([[,,],[,,],[,,]]) 转换成二维向量 vector = ...
- 17年iPhone炫酷铃声,mp3、m4r格式下载
下载链接: https://pan.baidu.com/s/11aj9dBm9upNWpE5jWBgYog
- java篇 之 流程控制语句
条件判断语句 条件语句: If(boolean类型) {} else {} (打大括号避免出错) switch (export)语句:export的类型必须是 byte,short,char,i ...
- 树莓派3B+(一)
第一步:安装raspbian系统 介绍:Raspbian是为树莓派设计,基于Debian的操作系统,由一个小团队开发.其不隶属于树莓派基金会,但被列为官方支持的操作系统. 下载地址:https://w ...
- 20165223《网络对抗技术》Exp2 后门原理与实践
目录 -- 后门原理与实践 后门原理与实践说明 实验任务 基础知识问答 常用后门工具 实验内容 任务一:使用netcat获取主机操作Shell,cron启动 任务二:使用socat获取主机操作Shel ...
- 利用反射将IDataReader读取到实体类中效率低下的解决办法
最开始使用反射一个类型的各个属性,对气进行赋值的代码如下: public static List<T> ToList<T>(IDataReader reader) { //实例 ...
- JS学习笔记Day24
一.闭包和函数 (一)什么是闭包函数 概念:简单说就是函数中嵌套函数,嵌套在这里面的函数叫做闭包函数,外面的函数叫做闭包环境 作用:通过闭包函数,可以访问到闭包函数所在局部作用域中的变量及参数 特点: ...
- (模拟 打好基础)nyoj1363-计划日
1363-计划日 内存限制:256MB 时间限制:3000ms 特判: No通过数:21 提交数:79 难度:1 题目描述: 为什么花那么多时间.精力还是学不好学不通,如何把握各科目的重难点,期中和期 ...
- Linux,Ubuntu,Mint 环境下 navicat 乱码问题
1. 官方下载好以后,进入目录 执行 ./start_navicat 可以启动软件. 2. 如果有乱码,首先,使用编辑器打开 start_navicat ,比如 vim start_navicat ...
- 分析web.xml
<?xml version="1.0" encoding="UTF-8"?> //xml的版本:1.0 和 编码:utf-8 <web-ap ...