http://acm.hdu.edu.cn/showproblem.php?pid=5510

想了很久队友叫我用ufs + kmp暴力过去了。

fa[x] = y表示x是y的子串,所以只有fa[x] == x才需要kmp一次。

那么这样的话,如果全部都不互为子串的话,复杂度还是爆咋的。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <queue>
  8. #include <string>
  9. #include <stack>
  10. #include <map>
  11. #include <set>
  12. #include <bitset>
  13. #include <cstdlib>
  14. #include <ctime>
  15. #define X first
  16. #define Y second
  17. #define clr(u,v); memset(u,v,sizeof(u));
  18. #define in() freopen("data.txt","r",stdin);
  19. #define out() freopen("ans","w",stdout);
  20. #define Clear(Q); while (!Q.empty()) Q.pop();
  21. #define pb push_back
  22. using namespace std;
  23. typedef long long ll;
  24. typedef pair<int, int> pii;
  25. const ll INF = 1e17;
  26. const int inf = 0x3f3f3f3f;
  27. const int maxn = + ;
  28. int tonext[][maxn];
  29. void get_next(char sub[], int tonext[], int lensub) {
  30. int i = , j = ;
  31. tonext[] = ;
  32. while (i <= lensub) {
  33. if (j == || sub[i] == sub[j]) {
  34. tonext[++i] = ++j;
  35. } else j = tonext[j];
  36. }
  37. }
  38. int kmp(char str[], char sub[], int lenstr, int lensub, int tonext[]) {
  39. int i = , j = ;
  40. while (i <= lenstr) {
  41. if (j == || str[i] == sub[j]) {
  42. ++i, ++j;
  43. } else j = tonext[j];
  44. if (j == lensub + ) return true;
  45. }
  46. return false;
  47. }
  48. char str[][maxn];
  49. int len[];
  50. int f;
  51. int fa[maxn];
  52. int tofind(int u) {
  53. if (fa[u] == u) return u;
  54. else return fa[u] = tofind(fa[u]);
  55. }
  56. void tomerge(int x, int y) {
  57. x = tofind(x), y = tofind(y);
  58. fa[y] = x;
  59. }
  60. void work() {
  61. int n;
  62. scanf("%d", &n);
  63. for (int i = ; i <= n; ++i) {
  64. scanf("%s", str[i] + );
  65. len[i] = strlen(str[i] + );
  66. get_next(str[i], tonext[i], len[i]);
  67. fa[i] = i;
  68. }
  69. printf("Case #%d: ", ++f);
  70. int ans = -;
  71. for (int i = ; i <= n; ++i) {
  72. for (int j = i - ; j >= ; --j) {
  73. if (tofind(j) != j) continue;
  74. if (kmp(str[i], str[j], len[i], len[j], tonext[j])) {
  75. tomerge(i, j); //合并的方向,小的合并去大的
  76. } else {
  77. ans = i;
  78. }
  79. // if (kmp(str[j], str[i], len[j], len[i], tonext[i])) {
  80. // tomerge(j, i);
  81. // }
  82. }
  83. }
  84. printf("%d\n", ans);
  85. return;
  86. }
  87.  
  88. int main() {
  89. #ifdef local
  90. in();
  91. #else
  92. #endif
  93. int t;
  94. scanf("%d", &t);
  95. while (t--) work();
  96. return ;
  97. }

有一个超时的AC自动机算法。复杂度O(T * n * lenstr * lenstr)

首先所有串buildFail

然后对于每一个串,爬Fail树。从后往前枚举

那么每个串跑一次Fail树的时候就能知道有多少个子串。成立的条件是子串个数 < i,则i位置成立。

如果后面的串使得匹配子串个数变大的话,那么是不影响的,说明在后面枚举的时候那个位置就应该是已经成立的了。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <queue>
  8. #include <string>
  9. #include <stack>
  10. #include <map>
  11. #include <set>
  12. #include <bitset>
  13. #include <cstdlib>
  14. #include <ctime>
  15. #define X first
  16. #define Y second
  17. #define clr(u,v); memset(u,v,sizeof(u));
  18. #define in() freopen("2.h","r",stdin);
  19. #define out() freopen("ans","w",stdout);
  20. #define Clear(Q); while (!Q.empty()) Q.pop();
  21. #define pb push_back
  22. using namespace std;
  23. typedef long long ll;
  24. typedef pair<int, int> pii;
  25. const ll INF = 1e17;
  26. const int inf = 0x3f3f3f3f;
  27. char str[][ + ];
  28. struct Node {
  29. int flag, id;
  30. struct Node *Fail;
  31. struct Node *pNext[];
  32. } tree[ + ];
  33. int t;
  34. struct Node * create() {
  35. struct Node * p = &tree[t++];
  36. p->flag = ;
  37. p->Fail = NULL;
  38. p->id = t - ;
  39. for (int i = ; i < ; ++i) p->pNext[i] = NULL;
  40. return p;
  41. }
  42. void toinsert(struct Node **T, char str[]) {
  43. struct Node *p = *T;
  44. if (p == NULL) p = *T = create();
  45. for (int i = ; str[i]; ++i) {
  46. int id = str[i] - 'a';
  47. if (p->pNext[id] == NULL) {
  48. p->pNext[id] = create();
  49. }
  50. p = p->pNext[id];
  51. }
  52. p->flag++;
  53. }
  54. struct Node * que[ + ];
  55. void BuildFlag(struct Node **T) {
  56. struct Node *p = *T;
  57. struct Node *root = *T;
  58. if (p == NULL) return ;
  59. int head = , tail = ;
  60. que[tail++] = root;
  61. while (head < tail) {
  62. p = que[head];
  63. for (int i = ; i < ; ++i) {
  64. if (p->pNext[i] != NULL) {
  65. if (p == root) {
  66. p->pNext[i]->Fail = root;
  67. } else {
  68. struct Node * FailNode = p->Fail;
  69. while (FailNode != NULL) {
  70. if (FailNode->pNext[i] != NULL) {
  71. p->pNext[i]->Fail = FailNode->pNext[i];
  72. break;
  73. }
  74. FailNode = FailNode->Fail;
  75. }
  76. }
  77. que[tail++] = p->pNext[i];
  78. } else if (p == root) {
  79. p->pNext[i] = root;
  80. } else {
  81. p->pNext[i] = p->Fail->pNext[i];
  82. }
  83. }
  84. head++;
  85. }
  86. }
  87. int vis[ + ], DFN;
  88. int searchAC(struct Node *T, char str[], int val) {
  89. DFN++;
  90. int ans = ;
  91. struct Node * p = T;
  92. struct Node * root = T;
  93. if (p == NULL) return ;
  94. for (int i = ; str[i]; ++i) {
  95. int id = str[i] - 'a';
  96. p = p->pNext[id];
  97. struct Node * temp = p;
  98. while (temp != root && vis[temp->id] != DFN) {
  99. vis[temp->id] = DFN;
  100. ans += temp->flag;
  101. temp = temp->Fail;
  102. if (ans >= val) return false;
  103. }
  104. }
  105. return true;
  106. }
  107. int f;
  108. void work() {
  109. t = ;
  110. printf("Case #%d: ", ++f);
  111. int n;
  112. scanf("%d", &n);
  113. struct Node * T = NULL;
  114. for (int i = ; i <= n; ++i) {
  115. scanf("%s", str[i] + );
  116. toinsert(&T, str[i]);
  117. }
  118. BuildFlag(&T);
  119. for (int i = n; i ; --i) {
  120. if(searchAC(T, str[i], i)) {
  121. printf("%d\n", i);
  122. return;
  123. }
  124. }
  125. printf("-1\n");
  126. return;
  127. }
  128.  
  129. int main() {
  130. #ifdef LOCAL
  131. in();
  132. #else
  133. #endif
  134. int t;
  135. scanf("%d", &t);
  136. while (t--) work();
  137. return ;
  138. }

Bazinga HDU - 5510 不可做的暴力的更多相关文章

  1. Bazinga HDU 5510 Bazinga(双指针)

    Bazinga HDU 5510 Bazinga(双指针) 题链 解法:对于串i来说,如果串i是不符合的,那么代表串i之前的字符串都是i的子串,那么我们求一个新的i(定义为ti),如果i是ti 的子串 ...

  2. Bazinga HDU - 5510【技巧暴力+字符串】

    题目:https://vjudge.net/problem/HDU-5510 $2015ACM/ICPC$ 亚洲区沈阳站 题目大意: 输入$t$(表示样例个数) 如何每个样例一个 $n$,表示字符串的 ...

  3. 【Bazinga HDU - 5510 】【考察strstr()的使用】【贪心】

    题意分析 1.题目大致说的是让你输出符合这种条件(在所给的字符串中至少有一个不是它的子串)的字符串对应的label,若没有输出-1: 2.判断子串可以用string.h下的strstr(s1, s2) ...

  4. hdu 5510 Bazinga(字符串kmp)

    Bazinga Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  5. HDU 2920 分块底数优化 暴力

    其实和昨天写的那道水题是一样的,注意爆LL $1<=n,k<=1e9$,$\sum\limits_{i=1}^{n}(k \mod i) = nk - \sum\limits_{i=1}^ ...

  6. HDU 5510 Bazinga 暴力匹配加剪枝

    Bazinga Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5510 ...

  7. HDU 5510:Bazinga(暴力KMP)

    http://acm.hdu.edu.cn/showproblem.php?pid=5510 Bazinga Problem Description   Ladies and gentlemen, p ...

  8. hdu 5510 Bazinga (KMP+暴力标记)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5510 思路: 一开始直接用KMP莽了发,超时了,后面发现如果前面的字符串被后面的字符串包含,那么我们就 ...

  9. hdu 5510 Bazinga(暴力)

    Problem Description Ladies and gentlemen, please sit up straight. Don't tilt your head. I'm serious. ...

随机推荐

  1. 洛谷【P1908】逆序对

    题目传送门:https://www.luogu.org/problemnew/show/P1908 所谓逆序对,就是序列中\(a[i]>a[j]\)且\(i<j\)的有序对. 所以我们在归 ...

  2. Fortify代码扫描解决方案

    Fortify扫描漏洞解决方案: Log Forging漏洞: 1.数据从一个不可信赖的数据源进入应用程序. 在这种情况下,数据经由getParameter()到后台. 2. 数据写入到应用程序或系统 ...

  3. Poj 3356 ACGT(LCS 或 带备忘的递归)

    题意:把一个字符串通过增.删.改三种操作变成另外一个字符串,求最少的操作数. 分析: 可以用LCS求出最大公共子序列,再把两个串中更长的那一串中不是公共子序列的部分删除. 分析可知两个字符串的距离肯定 ...

  4. nginx实现带参数目录域名重定向二级域名方法

    本文章介绍了关于nginx实现带参数目录域名重定向二级域名方法,有需要学习的朋友可参考一下. 下面的代码是基于nginx的子目录301到其他域名(URL)的规则.作用是例如访问http://www.p ...

  5. RESTEasy常用注解

    一.@Path,标注资源类或方法的相对路径          Path参数的形式有三种:          1.固定值          2.纯正则表达式          3.固定值和正则表达式的混 ...

  6. 启动新内核出现:Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004

    转载请注明出处:http://blog.csdn.net/qq_26093511/article/details/51841281 启动新内核出现错误:Kernel panic - not synci ...

  7. LAMP 1.2 Apache编译安装问题解决

    这个错误安装 yum install -y gcc error: mod_deflate has been requested but can not be built due to prerequi ...

  8. 阶段2-新手上路\项目-移动物体监控系统\Sprint1-声音报警子系统开发\第1节-Sprint Backlog规划

    根据之前的sprint1-声音报警子系统是相对比较大的一个需求,需要把它进一步细化,然后指定sprint Backlog product Backlog是整个产品的功能列表! sprint Backl ...

  9. JavaScript中的构造函数和工厂函数说明

    在cnblog上看到一篇文章,讲解JS中的构造函数和工厂函数,觉得讲的真好 JavaScript中的工厂函数和构造函数都能用来创建一个对象,我们可以来看看下面的例子 构造函数 function cre ...

  10. CSS定位机制总结

    1,CSS 有三种基本的定位机制:普通流.浮动和绝对定位.除非专门指定,否则所有框都在普通流中定位.2,普通流定位:块级框从上到下一个接一个地排列,框之间的垂直距离是由框的垂直外边距计算出来.行内框在 ...