题目链接:

  Poj 3294 Life Forms

题目描述:

  有n个文本串,问在一半以上的文本串出现过的最长连续子串?

解题思路:

  可以把文本串用没有出现过的不同字符连起来,然后求新文本串的height。然后二分答案串的长度K,根据K把新文本串的后缀串分块,统计每块中的原文本串出现的次数,大于原文本串数目的一半就作为答案记录下来,对于输出字典序,height就是排好序的后缀数组,只要按照顺序输出即可。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. using namespace std;
  6. typedef long long LL;
  7. const int maxn = ;
  8.  
  9. int sa[maxn], rank[maxn], height[maxn], vis[], res[maxn];
  10. int t1[maxn], t2[maxn], r[maxn], flag[maxn], c[maxn];
  11.  
  12. bool cmp (int *str, int a, int b, int k)
  13. {
  14. return str[a]==str[b] && str[a+k]==str[b+k];
  15. }
  16.  
  17. void da (int *str, int n, int m)
  18. {
  19. n ++;
  20. int *x = t1, *y = t2, i, j;
  21.  
  22. for (i=; i<m; i++) c[i] = ;
  23. for (i=; i<n; i++) c[x[i]=str[i]] ++;
  24. for (i=; i<m; i++) c[i] += c[i-];
  25. for (i=n-; i>=; i--) sa[-- c[x[i]]] = i;
  26.  
  27. for (j=; j<=n; j*=)
  28. {
  29. int p = ;
  30. for (i=n-j; i<n; i++) y[p++] = i;
  31. for (i=; i<n; i++) if (sa[i] >= j) y[p++] = sa[i] - j;
  32.  
  33. for (i=; i<m; i++) c[i] = ;
  34. for (i=; i<n; i++) c[x[y[i]]] ++;
  35. for (i=; i<m; i++) c[i] += c[i-];
  36. for (i=n-; i>=; i--) sa[-- c[x[y[i]]]] = y[i];
  37.  
  38. swap (x, y);
  39. p = ;
  40. x[sa[]] = ;
  41. for (int i=; i<n; i++)//i是rank
  42. x[sa[i]] = cmp(y, sa[i-], sa[i], j)?p-:p++;
  43. if (p >= n)
  44. break;
  45. m = p;
  46. }
  47.  
  48. for (i=; i<n; i++)
  49. rank[sa[i]] = i;
  50.  
  51. int k = ;
  52. n --;
  53. for (int i=; i<n; i++)
  54. {
  55. if (k) k --;
  56. int j = sa[rank[i] - ];
  57. while (str[i+k] == str[j+k]) k++;
  58. height[rank[i]] = k;
  59. }
  60. }
  61.  
  62. bool Bin_sreach (int x, int k, int n)
  63. {
  64. int ans, num;
  65. ans = num = ;
  66. memset (vis, , sizeof(vis));
  67.  
  68. for (int i=; i<=k; i++)
  69. {
  70. if (height[i] >= x)
  71. {
  72. ans += vis[flag[sa[i-]]]?:;
  73. vis[flag[sa[i-]]] = ;
  74.  
  75. ans += vis[flag[sa[i]]]?:;
  76. vis[flag[sa[i]]] = ;
  77. }
  78. else
  79. {
  80. if (ans* > n)
  81. res[++ num] = sa[i-];
  82.  
  83. ans = ;
  84. memset (vis, , sizeof(vis));
  85. }
  86. }
  87. if (ans* > n)
  88. res[++ num] = sa[k-];
  89.  
  90. if (num)
  91. {
  92. res[] = num;
  93. return true;
  94. }
  95. return false;
  96. }
  97.  
  98. int main ()
  99. {
  100. int n, l = ;
  101. char str[];
  102. while (scanf ("%d", &n), n)
  103. {
  104. if (l ++)
  105. printf ("\n");
  106.  
  107. int k = ;
  108. for (int i=; i<n; i++)
  109. {
  110. scanf ("%s", str);
  111. for (int j=; str[j]; j++)
  112. {
  113. r[k] = str[j];
  114. flag[k++] = i;//记录k字母所在的字符串
  115. }
  116. r[k] = + i;
  117. flag[k++] = -;
  118. }
  119.  
  120. r[k] = ;
  121. da (r, k, );
  122.  
  123. int low = , high = k, mid, ans = ;
  124. while (low <= high)
  125. {//二分枚举
  126. mid = (low + high) / ;
  127. if (Bin_sreach(mid, k, n))
  128. {
  129. ans = mid;
  130. low = mid + ;
  131. }
  132. else
  133. high = mid - ;
  134. }
  135.  
  136. if (low == )
  137. {
  138. printf ("?\n");
  139. continue;
  140. }
  141.  
  142. for (int i=; i<=res[]; i++)
  143. {
  144. for (int j=res[i]; j<res[i]+ans; j ++)
  145. printf ("%c", r[j]);
  146. printf ("\n");
  147. }
  148. }
  149. return ;
  150. }

Poj 3294 Life Forms (后缀数组 + 二分 + Hash)的更多相关文章

  1. poj 3294 Life Forms - 后缀数组 - 二分答案

    题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...

  2. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

    Life Forms   Description You may have wondered why most extraterrestrial life forms resemble humans, ...

  3. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  4. [poj 1743] Musical Theme 后缀数组 or hash

    Musical Theme 题意 给出n个1-88组成的音符,让找出一个最长的连续子序列,满足以下条件: 长度大于5 不重叠的出现两次(这里的出现可以经过变调,即这个序列的每个数字全都加上一个整数x) ...

  5. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  6. POJ 1226 Substrings(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=1226 [题目大意] 求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的. [题解] 我们将每个字符串倒置,用 ...

  7. BZOJ 4278: [ONTAK2015]Tasowanie (后缀数组 / 二分+hash)

    直接归并,然后如果哪边的后缀字典序比较小就去哪边,然后就可以后缀数组 博客传送门- 但是本蒟蒻不会后缀数组 Upd:Upd:Upd:现在会了233.一道差不多的题:BZOJ 1692: [Usaco2 ...

  8. BZOJ 1692: [Usaco2007 Dec]队列变换 (后缀数组/二分+Hash)

    跟BZOJ 4278: [ONTAK2015]Tasowanie一模一样 SA的做法就是把原串倒过来接在原串后面,O(nlogn)O(nlogn)O(nlogn)做后缀数组,就能O(1)O(1)O(1 ...

  9. POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串

                                                                              Life Forms Time Limit: 500 ...

随机推荐

  1. Building clang on RedHat

    http://btorpey.github.io/blog/2015/01/02/building-clang/ clang is a great compiler, with a boatload ...

  2. kvm虚拟化学习笔记(四)之kvm虚拟机日常管理与配置

    KVM虚拟化学习笔记系列文章列表----------------------------------------kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51 ...

  3. CV_HAAR_FEATURE_DESC_MAX和CV_HAAR_FEATURE_MAX

    #define CV_HAAR_FEATURE_MAX 3 //提前定义的一个宏,在程序中表示一个haar特征由至多三个矩形组成 #define CV_HAAR_FEATURE_DESC_MAX 20 ...

  4. nagios 安装配置(包含nrpe端)全 (三)

    四.系统的配置: 1.介绍 在配置过程中涉及到的几个定义有:主机.主机组,服务.服务组.联系人.联系人组,监控时间.监控命令等. 最重要的有四点: 第一:定义监控哪些主机.主机组.服务和服务组: 第二 ...

  5. Linux(Ubuntu14.04)下Google Chrome / Chromium标题栏乱码问题

    注:我使用的Linux发行版是Ubuntu 14.04,不同Linux发行版可能会有不同. 最近在使用Chromium的时候tab的标题栏中文显示乱码,在地址栏输入中文是同样时乱码,就像下图: 看起来 ...

  6. Java中有多少种设计模式?请简单画一下三种常见设计模式的类图?

    转载:http://blog.csdn.net/longyulu/article/details/9159589 一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽 ...

  7. docker启动centos容器后如何用putty连接

    在前面的文章中,我提到过,win10 docker启动容器时,只有配置了宿主机和docker容器的端口映射,外部应用才能访问到容器中的服务,比如映射到Nginx的80端口.现在我将宿主机的某个端口映射 ...

  8. MongoDB相关的一些技术文章

    安装 win7下安装和配置MongoDB的总结---阿冬专栏

  9. 计算机设计思想 —— 代理(proxy)

    0. 理解 两个说着不同母语国家的人想要交流通话,各人说着各自的母语显然是无法沟通的,此时需要一个翻译,一个媒介(medium).中介,或者一个代理(proxy),比如通用的国际语言英语,比如全世界人 ...

  10. 【转】js中15个常用的正则表达式+正则集合

    1 用户名正则 //用户名正则,4到16位(字母,数字,下划线,减号) var uPattern = /^[a-zA-Z0-9_-]{4,16}$/; //输出 true console.log(uP ...