P3966 [TJOI2013]单词

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:

  1. 3
  2. a
  3. aa
  4. aaa
输出样例#1:

  1. 6
  2. 3
  3. 1

说明

数据范围

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

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

看上去题目貌似很简单,不就是把trie树一建然后对每个单词跑一遍AC自动机吗?然而这样会被卡死,考虑如何来优化,由于题目中说每一个单词会多次出现,那么我们就可以统计一下每个单词出现的次数,把这个出现次数看做这个单词的权值,然后在跑AC自动机时直接把这个权值加入到答案中,那么我们如何处理重复出现的单词并统计次数呢?其实我们在trie树上就可以搞定,如果两个单词相同,那么他们在trie树上的结束节点一定相同,这样就可以进行统计了。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<string>
  5. #include<cstring>
  6. #include<map>
  7. #include<queue>
  8. #include<stack>
  9. #include<algorithm>
  10. #include<vector>
  11. #define maxn 1050005
  12. using namespace std;
  13.  
  14. inline int read()
  15. {
  16. char c=getchar();
  17. int res=,x=;
  18. while(c<''||c>'')
  19. {
  20. if(c=='-')
  21. x=-;
  22. c=getchar();
  23. }
  24. while(c>=''&&c<='')
  25. {
  26. res=res*+(c-'');
  27. c=getchar();
  28. }
  29. return res*x;
  30. }
  31.  
  32. int n,tot=;
  33. int tree[maxn][],nt[maxn],bo[maxn],ed[maxn],f[maxn],t[maxn];
  34. char a[][maxn];
  35. queue<int>q;
  36.  
  37. void trie(char *s,int num)
  38. {
  39. int len=strlen(s),u=;
  40. for(register int i=;i<len;i++)
  41. {
  42. int c=s[i]-'a';
  43. if(!tree[u][c])
  44. {
  45. tree[u][c]=++tot;
  46. }
  47. u=tree[u][c];
  48. }
  49. if(bo[u])
  50. t[num]=;//t数组表示这个单词之前是否出现过
  51. bo[u]++;
  52. ed[num]=u;
  53. }
  54.  
  55. void bfs()
  56. {
  57. for(register int i=;i<;i++)
  58. {
  59. tree[][i]=;
  60. }
  61. nt[]=;q.push();
  62. while(q.size())
  63. {
  64. int u=q.front();q.pop();
  65. for(register int i=;i<;i++)
  66. {
  67. if(!tree[u][i])
  68. tree[u][i]=tree[nt[u]][i];
  69. else
  70. {
  71. int v=tree[u][i];
  72. q.push(v);
  73. nt[v]=tree[nt[u]][i];
  74. }
  75. }
  76. }
  77. }
  78.  
  79. void find(char *s,int num)
  80. {
  81. int len=strlen(s),u=,k,ans=bo[ed[num]];//ans表示这个单词出现的次数
  82. for(register int i=;i<len;i++)
  83. {
  84. int c=s[i]-'a';
  85. k=tree[u][c];
  86. while(k>)
  87. {
  88. if(bo[k])
  89. f[k]+=ans;
  90. k=nt[k];
  91. }
  92. u=tree[u][c];
  93. }
  94. }
  95.  
  96. int main()
  97. {
  98. n=read();
  99. for(register int i=;i<=n;i++)
  100. {
  101. scanf("%s",a[i]);
  102. trie(a[i],i);
  103. }
  104. bfs();
  105. for(register int i=;i<=n;i++)
  106. {
  107. if(!t[i])//这里我们只需要将每个不重复出现的单词跑一边AC自动机
  108. find(a[i],i);
  109. }
  110. for(register int i=;i<=n;i++)
  111. {
  112. printf("%d\n",f[ed[i]]);
  113. }
  114. return ;
  115. }

P3966 [TJOI2013]单词的更多相关文章

  1. 洛谷P3966 [TJOI2013]单词(fail树性质)

    P3966 [TJOI2013]单词 题目链接:https://www.luogu.org/problemnew/show/P3966 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...

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

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

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

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

  4. Luogu P3966 [TJOI2013]单词

    题目链接 \(Click\) \(Here\) 本题\(AC\)自动机写法的正解之一是\(Fail\)树上跑\(DP\). \(AC\)自动机是\(Trie\)树和\(Fail\)树共存的结构,前者可 ...

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

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

  6. 【洛谷】3966:[TJOI2013]单词【AC自动机】【fail树】

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

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

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

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

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

  9. 3172: [Tjoi2013]单词

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

随机推荐

  1. Nginx访问配置

    配置HTTP协议(使用80默认端口,非HTTPS配置SSL)访问网站 包括RestAPI的配置和RestAPI文档的配置 例如: server { # 配置为HTTP协议 listen ; serve ...

  2. 在ConoHa上Centos7环境下源码安装部署LNMP

    本文记录了从源码,在Centos 7上手动部署LNMP环境的过程,为了方便以后对nginx和mariadb进行升级,这里采用yum的方式进行安装. 1.建立运行网站和数据库的用户和组 groupadd ...

  3. centos 桌面没有有线设置,不能上网

    1.ifconfig 发现缺少网卡 ensxx 2.cd /etc/sysconfig/network-scripts/  发现有网卡ens的配置文件,只是没有启动 3.ifconfig -a 发现有 ...

  4. C++中typedef enum 和 enum

    在C++中,这两种定义枚举类型的关键字用法和效果相同,推荐使用前者.typedef enum多用在C语言中. 在C语言中,如果使用typedef enum定义一个枚举类型,比如: typedef en ...

  5. Codeforces Global Round 1 A~F

    失踪人口回来写题了.. 写了几乎一下午.贴一贴代码以及口糊一下. A. 题意:计算一下这个多项式的和. 题解:暴力算一算对每一项异或一下. #include<bits/stdc++.h> ...

  6. Event filter with query "SELECT * FROM __InstanceModi

    Event filter with query "SELECT * FROM __InstanceModi     问题描述: Details -Event filter with quer ...

  7. 2018-2019-2 实验二 Java面向对象程序设计

    实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承.多态 3.初步掌握UML建模 4.熟悉S.O.L.I.D原则 5.了解设计模式 实验要求 1.没有Linux基础的同学 ...

  8. Linux ip配置

    ifconfig  查看ip ifconfig eth0  192.168.100.10  netmask 255.255.255.0  或者 ifconfig eth0  192.168.100.1 ...

  9. XGBoost参数调优完全指南

    简介 如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧.XGBoost算法现在已经成为很多数据工程师的重要武器.它是一种十分精致的算法,可以处理各种不规则的数据.构造一个使用XGBoost ...

  10. C#中Dictionary的介绍

    关键字:C# Dictionary 字典 作者:txw1958原文:http://www.cnblogs.com/txw1958/archive/2012/11/07/csharp-dictionar ...