#3831 TJOI2013单词
WOJ#3831 TJOI2013单词
题面
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
输入
第一个一个整数 N ,表示有多少个单词,接下来 N 行每行一个单词。
输出
输出 N 个整数,第 i 行的数字表示第 i 个单词在文章中出现了多少次。
样例输入
3
a
aa
aaa
样例输出
6
3
1
提示
对于全部数据,1≤N≤200 ,所有单词长度的和不超过 106,保证每个单词由小写字母组成。
题解
本题中,第2行到第N+1行构成论文,同时每一行也是单词,所以我们可以用AC自动机求解,依次用每一个单词进行匹配,每次匹配到一个单词的结尾时,就在ans数组中对应这个结尾的单词序号的位置记录答案。
但是想一想就会发现上述方法不但会超时,还可能在单词出现重复时出错(Trie树上记录单词结尾时只能记录一个单词的序号,遇到重复时重复单词会因此得到0,笔者最初就是因为没考虑这一点而错误)。因此我们可以用一个sme数组来记录每一种单词的序号,同时在Trie树上记录单词结尾时记录这种单词的序号。再进一步思考可以发现,如果我们把每个单词的重复次数用tim数组记录下来,就可以避免因重复查询带来的超时。
代码
#include<bits/stdc++.h>
using namespace std;
#define N 1000010
int n,tot,ans[N],nxt[N],sme[N],tim[N],vis[N],ch[N][];
char CH[][];
void build(char *s,int ord){
int u=,len=strlen(s);
for(int i=;i< len;i++){
int c=s[i]-'a';
if(!ch[u][c]){ch[u][c]=++tot;memset(ch[tot],,sizeof(ch[tot]));}
u=ch[u][c];
}
if(!vis[u]){vis[u]=ord;sme[ord]=ord;tim[ord]=;}
else{sme[ord]=vis[u];tim[vis[u]]++;}
return ;
}
void bfs(){
queue<int>q;
for(int i=;i<=;i++) ch[][i]=;
q.push();nxt[]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=;i<=;i++){
if(!ch[u][i]){ch[u][i]=ch[nxt[u]][i];continue;}
q.push(ch[u][i]);
int v=nxt[u];nxt[ch[u][i]]=ch[v][i];
}
}
}
void find(char *s,int num){
int u=,len=strlen(s);
for(int i=;i<=len;i++){
int c=s[i]-'a',k=ch[u][c];
while(k>){
if(vis[k]) ans[vis[k]]+=num;
k=nxt[k];
}
u=ch[u][c];
}
return ;
}
int main(){
scanf("%d",&n);tot=;
for(int i=;i<=n;i++){scanf("%s",CH[i]);build(CH[i],i);}
bfs();
for(int i=;i<=n;i++){if(sme[i]==i) find(CH[i],tim[i]);}
for(int i=;i<=n;i++){printf("%d\n",ans[sme[i]]);}
return ;
}
#3831 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 ...
- BZOJ 3172([Tjoi2013]单词-后缀数组第一题+RMQ)
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 268 Solved: 145 [ Submit][ St ...
- [TJOI2013]单词
2755: [TJOI2013]单词 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 6 Solved: 3[Submit][Status][Web B ...
- P3966 [TJOI2013]单词
P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...
- 【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】
P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...
- bzoj 3172: [Tjoi2013]单词 AC自动机
3172: [Tjoi2013]单词 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ3172 [Tjoi2013]单词 【AC自动机】
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 4293 Solved: 2083 [Submit][Stat ...
随机推荐
- neo4j图形数据库Java应用
CREATE (陈冠希:明星 {名称: "陈冠希"}), (王菲:明星 {名称: "王菲"}), (李亚鹏:明星 {名称: "李亚鹏"}), ...
- VS #include 【bits/bstdc++.h】出错
目录 1. 本文地址 2. 按 3. 操作步骤 1. 本文地址 博客园:https://www.cnblogs.com/coco56/p/11163142.html 简书:https://www.ji ...
- 安装FaaS
[root@localhost ~]# [root@localhost ~]# new OS:centos-7 [root@localhost ~]# [root@localhost ~]# vim ...
- docker安装es
下载镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:6.8.1 创建容器并映射docker run -e ES_JAVA_OP ...
- 伪类和伪元素,review
总是分不太清楚,然后容易忘记这个概念,项目中又遇到了,复习一遍 问题 1.哪些常用的伪类?伪元素? 怎么记: 除了4个伪元素,其他都是伪类 哪四个伪元素?:before :after :first-l ...
- fiddler 手机抓包,CS端抓包 使用记录
1.允许远程连接 2.忽略https证书错误 3.设置代理 4.重启fiddle 5.PC客户端抓包分工具FIddler+Proxifer https://blog.csdn.net/sunbo_cs ...
- 设置div 居中 和得到dom元素高度
javascript中获取dom元素高度和宽度的方法如下: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网 ...
- Mybatis(三)MyBatis 注解方式的基本 用法
在 MyBatis注解 SQL 中,最基本的就是@Select.@Insert.@Update 和@Delete 四种.
- Categorical Data
This is an introduction to pandas categorical data type, including a short comparison with R's facto ...
- margin 和padding 的区别
margin是用来隔开元素与元素的间距:padding是用来隔开元素与内容的间隔.margin用于布局分开元素使元素与元素互不相干: padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元 ...