题目链接【http://www.lydsy.com/JudgeOnline/problem.php?id=1212】

题意:给你一些单词,然后给出一个没有标点的文本串S,都是小写字符。现在让你求用给出的单词组成文本串T,求S和T的最长公共前缀。

题解:AC自动机 + 背包,背包dp[i],表示是否能组成长度为【1,i】的前缀,在自动机中维护Len[i],表示第i个节点到根节点的距离,End[i],节点i是否是某个单词的结尾。在查询的时候,我们只需要在对应的Trie上跳就可以了,时间复杂度为x * N*log(N)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 1024 * 1024 + 15;
  4. int dp[maxn];
  5. struct Aho_C
  6. {
  7. int Next[maxn][26], Fail[maxn], End[maxn], Len[maxn];
  8. int root, sz;
  9. int newnode()
  10. {
  11. for(int i = 0; i < 26; i++)
  12. Next[sz][i] = -1;
  13. End[sz++] = 0;
  14. return sz - 1;
  15. }
  16. void init()
  17. {
  18. sz = 0;
  19. root = newnode();
  20. }
  21. void Insert(char buf[])
  22. {
  23. int len = strlen(buf);
  24. int now = root;
  25. for(int i = 0; i < len; i++)
  26. {
  27. if(Next[now][buf[i] - 'a'] == -1)
  28. Next[now][buf[i] - 'a'] = newnode();
  29. now = Next[now][buf[i] - 'a'];
  30. Len[now] = i + 1;
  31. }
  32. End[now]++;
  33. }
  34. void Build()
  35. {
  36. queue<int>Q;
  37. Fail[root] = root;
  38. for(int i = 0; i < 26; i++)
  39. if(Next[root][i] == -1)
  40. Next[root][i] = root;
  41. else
  42. {
  43. Fail[Next[root][i]] = root;
  44. Q.push(Next[root][i]);
  45. }
  46. while( !Q.empty() )
  47. {
  48. int now = Q.front();
  49. Q.pop();
  50. for(int i = 0; i < 26; i++)
  51. if(Next[now][i] == -1)
  52. Next[now][i] = Next[Fail[now]][i];
  53. else
  54. {
  55. Fail[Next[now][i]] = Next[Fail[now]][i];
  56. Q.push(Next[now][i]);
  57. }
  58. }
  59. }
  60. void Query(char buf[])
  61. {
  62. int len = strlen(buf + 1);
  63. int now = root;
  64. for(int i = 1; i <= len; i++)
  65. {
  66. dp[i] = 0;
  67. now = Next[now][buf[i] - 'a'];
  68. int temp = now;
  69. int tmp = Len[temp];
  70. while( temp != root)
  71. {
  72. if(End[temp])
  73. {
  74. int pos = i - Len[temp];
  75. dp[i] = max(Len[temp] + dp[pos], dp[i]);
  76. }
  77. temp = Fail[temp];
  78. }
  79. }
  80. }
  81. } ac;
  82. char buf[maxn * 2];
  83. int main()
  84. {
  85. int N, M;
  86. scanf("%d %d", &N, &M);
  87. ac.init();
  88. for(int i = 1; i <= N; i++)
  89. {
  90. scanf("%s", buf);
  91. ac.Insert(buf);
  92. }
  93. ac.Build();
  94. for(int i = 1; i <= M; i++)
  95. {
  96. scanf("%s", buf + 1);
  97. ac.Query(buf);
  98. int len = strlen(buf + 1);
  99. int ma = 0;
  100. for(int i = len; i >= 1; i--)
  101. {
  102. if(dp[i] == i)
  103. {
  104. ma = i;
  105. break;
  106. }
  107. }
  108. printf("%d\n", ma);
  109. }
  110. return 0;
  111. }

  

BZOJ 1212 [HNOI2004]L语言 【AC自动机 + 背包】的更多相关文章

  1. BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1367  Solved: 598[Submit][Status ...

  2. bzoj 1212: [HNOI2004]L语言 AC自动机+状压

    为什么这道题网上所有题解写的都是N*Len的trie树的暴力啊,4E的复杂度... 为什么暴力还跑这么快啊TAT.. 有一个O(Len)的做法就是先把AC自动机建出来,因为每个字典串的长度很小,所以我 ...

  3. BZOJ 1212 HNOI2004 L语言 AC自己主动机(Trie树)+动态规划

    标题效果:给定词的列表,并m串 每个字符串q个最长前缀,这个前缀可满足拆分成一些字符串 这些字符串中存在的词汇太 再也不怕错误的数据范围--有一个很明显Trie树能解决的问题竟然被我写的AC自己主动机 ...

  4. BZOJ 1212: [HNOI2004]L语言( dp + trie )

    因为单词很短...用trie然后每次dp暴力查找...用哈希+dp应该也是可以的.... ------------------------------------------------------- ...

  5. [HNOI2004] L语言 - AC自动机,dp

    给定字典和没有标点的文章,求能够被识别的最长前缀. 显然不能贪心,设\(f[i]\)表示前\(i\)个字符构成的前缀能否被识别,然后在AC自动机上暴力转移即可. 具体来说,每走到一个新位置,就沿着fa ...

  6. 【bzoj1212】[HNOI2004]L语言 AC自动机

    题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...

  7. bzoj 1212: [HNOI2004]L语言

    思路:字典树+dp, dp[ i ] 表示 前缀到 i 能不能被理解, 如果dp[ i ] 是能被理解的那么, 把i + 1, i + 2 ....  在字典树上走,走到一个单词就转移. ,这样可行的 ...

  8. BZOJ 1212: [HNOI2004]L语言 trie

    长度小于 10 是关键信息~ #include <cstdio> #include <cstring> #include <algorithm> #define N ...

  9. 1212: [HNOI2004]L语言

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 643  Solved: 252[Submit][Status] ...

随机推荐

  1. python最大最小距离算法贴近度评价法

    1.大最小贴近度评价法 概念: 贴近度表示两个模糊几何之间的彼此接近程度,在模糊模式识别方法中采用贴近度的大小识别待判别模糊子集的模式类别.为衡量待识别子集的类别,需要判别各个阶段与标杆模糊集合之间的 ...

  2. JavaScript辅助响应式

    js响应式 rem辅助响应式布局:其实就是指在HTML页面的大小不断变化的时候,里面的宽.高.字体等等也随之变化,主要是通过获取window.innerwidth的值来进行判断,7.5rem===10 ...

  3. Solr管理索引库——(十三)

    a)          维护索引 1.  添加/更新文档 添加或更新单个文档

  4. 【内核】几个重要的linux内核文件【转】

    转自:http://www.cnblogs.com/lcw/p/3159394.html Preface 当用户编译一个linux内核代码后,会产生几个文件:vmlinz.initrd.img, 以及 ...

  5. nginx自定义500,502,504错误页面无法跳转【转】

    1.自定一个页面,这个页面是一个链接地址可以直接访问的. 以下是nginx的配置: location / {            proxy_pass http://tomcat_app108;   ...

  6. c++语言知识点汇总

    c++ primer version-5 的整理 section 1: 内置类型和自定义类型: main函数的返回值:指示状态.0:成功:1:系统定义. unix和win系统中,执行完程序可以使用ec ...

  7. Django 内置模板标签和过滤器

    一.内置模板标签 语法:{%  %} autoescape : 是否转义,on或off作为参数,并确定自动转义是否在块内有效.该块以endautoescape结束 {% autoescape on % ...

  8. jQuery基本筛选器-表单筛选器-关系筛选器

    一.基本筛选器 :first // 第一个 :last // 最后一个 :eq(index)// 索引等于index的那个元素 :even // 匹配所有索引值为偶数的元素,从 0 开始计数 :odd ...

  9. VBA笔记-参考教程

    参考教程1: http://www.cnblogs.com/wuzhiblog/tag/VBA/ 1. VBA中字符换行 VBA中字符换行显示需要使用换行符来完成.下面是常用的换行符          ...

  10. java基础76 web服务器之Tomcat服务器

    (注:本文是以“压缩版Tomcat”为例,展开描述的) 一.Tomcat服务器的介绍 1.服务器 1.1.服务器的种类 从物理上讲:服务器就是一台pc机器.至少8核/8G以上.内存至少用T来计算.宽带 ...