经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
[luogu2292][L语言]
来源:cnblogs  作者:wxyww  时间:2018/12/17 11:53:08  对本文有异议

题目链接

思路

这道题我用的是AC自动机的做法。

先把子串挂到tried树上,在单词结尾打标记的时候,标记的是当前单词的长度。然后去上面查询母串的时候,每查询到一个单词,就建立一条线段,这条线段的结尾位置是母串当前的位置,开始位置就是用当前位置减去这个单词的长度。

然后只要去判断,选出一些线段,使得这些线段紧挨着(既不相互覆盖,中间也不遗漏)从母串开始位置铺,能铺到的最远的地方。所以只需要一遍bfs就行了。

代码

  1. /*
  2. * @Author: wxyww
  3. * @Date: 2018-12-17 08:38:38
  4. * @Last Modified time: 2018-12-17 09:09:28
  5. */
  6. #include<cstdio>
  7. #include<iostream>
  8. #include<cstdlib>
  9. #include<cmath>
  10. #include<ctime>
  11. #include<bitset>
  12. #include<cstring>
  13. #include<queue>
  14. using namespace std;
  15. typedef long long ll;
  16. const int N = 2000000 + 100;
  17. ll read() {
  18. ll x=0,f=1;char c=getchar();
  19. while(c<'0'||c>'9') {
  20. if(c=='-') f=-1;
  21. c=getchar();
  22. }
  23. while(c>='0'&&c<='9') {
  24. x=x*10+c-'0';
  25. c=getchar();
  26. }
  27. return x*f;
  28. }
  29. int trie[1000][30],end[1000];
  30. char s[30];
  31. int tot;
  32. void insert() {
  33. int len = strlen(s + 1);
  34. int now = 0;
  35. for(int i = 1;i <= len;++i) {
  36. int k = s[i] - 'a';
  37. if(!trie[now][k]) trie[now][k] = ++tot;
  38. now = trie[now][k];
  39. }
  40. end[now] = len;
  41. }
  42. struct node {
  43. int l,r;
  44. }e[N];
  45. int ejs;
  46. int fail[N];
  47. char S[N];
  48. queue<int>q;
  49. void build() {
  50. for(int i = 0;i < 26;++i) if(trie[0][i]) q.push(trie[0][i]);
  51. while(!q.empty()) {
  52. int u = q.front();q.pop();
  53. for(int i = 0;i < 26;++i) {
  54. if(trie[u][i]) fail[trie[u][i]] = trie[fail[u]][i],q.push(trie[u][i]);
  55. else trie[u][i] = trie[fail[u]][i];
  56. }
  57. }
  58. }
  59. vector<int>v[N];
  60. void work() {
  61. int len = strlen(S + 1);
  62. ejs = 0;int now = 0;
  63. for(int i = 1;i <= len;++i) {
  64. now = trie[now][S[i] - 'a'];
  65. for(int j = now;j;j = fail[j]) {
  66. if(end[j]) e[++ejs].l = i - end[j] + 1,e[ejs].r = i;
  67. }
  68. }
  69. }
  70. int vis[N];
  71. void bfs() {
  72. q.push(1);
  73. int ans = 0;
  74. for(int i = 1;i <= ejs;++i) v[e[i].l].push_back(i);
  75. memset(vis,0,sizeof(vis));
  76. while(!q.empty()) {
  77. int l = q.front();q.pop();
  78. int k = v[l].size();
  79. for(int i = 0;i < k;++i) {
  80. int z = v[l][i];
  81. if(vis[z]) continue;
  82. vis[z] = 1;
  83. q.push(e[z].r + 1);
  84. ans = max(ans,e[z].r);
  85. }
  86. }
  87. printf("%d\n",ans);
  88. int len = strlen(S + 1);
  89. for(int i = 1;i <= len;++i) v[i].clear();
  90. }
  91. int main() {
  92. int n = read(),m = read();
  93. for(int i = 1;i <= n;++i) {
  94. scanf("%s",s + 1);
  95. insert();
  96. }
  97. build();
  98. for(int i = 1;i <= m;++i) {
  99. scanf("%s",S + 1);
  100. work();
  101. bfs();
  102. }
  103. return 0;
  104. }
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号