Description

In the deep universe, there is a beautiful planet named as CS on which scientists have decided to build Immense Colossal Particle Collider (i.e. ICPC) to find the ultimate theory of the universe. The ICPC is made up with several fragments, and each fragment
has a series of energy level. Any continuous sub-series of energy level corresponds to one type of microscopic particle and can accelerate it with a remarkable effect. Scientists have found that the observation of the certain type of particle is remarkable
enough if its corresponding energy level sub-series appears in more than one half fragments. Another thing, the reverse of one specific sub-series of energy level corresponds to the antiparticle of the particle corresponded by its original sub-series. As we
all know, when a particle meets its antiparticle, DUANG DUANG, a very remarkable phenomenon can be observed by scientists. For simplicity, scientists have declared that it is not remarkable enough until the total count of the appearance in the different fragments
of the original sub-series and its reverse is more than one half the number of fragments. Lastly, both in the first and the second condition, the longer the sub-series is, the more remarkable observation can be get.

Well, so long a paragraph, science is really complicated. Now, questions come: given a set of fragments with a series of energy level, find the sub-series which can get the most remarkable observation.

Input

There are several cases. Every case comes a line with a positive integer N (N <= 10) first of all, followed by N lines each of which contains a nonempty series of capital letters representing energy levels. All series have a length not more than 1000.

Output

For every case, output the wanted sub-series. If there are more than one, output them in the alphabetical order, each in one line. If there is none, output NONE. Note that whenever one sub-series and its reverse appear simultaneously with the satisfied condition,
it is available to output only the less one in alphabetical order of them two even if any of them two appears more than one half N times.

Sample Input

  1. 3
  2. ABC
  3. ABD
  4. BCD
  5. 3
  6. AAA
  7. BBB
  8. CCC
  9. 2
  10. ABC
  11. DBA

Sample Output

  1. AB
  2. BC
  3. NONE
  4. AB

HINT

Source



题意:
要求全部正向或者反向出如今超过k/2个串中的子串

思路:
还是和曾经一样二分答案。使用二进制来标记状态

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stack>
  5. #include <queue>
  6. #include <map>
  7. #include <set>
  8. #include <vector>
  9. #include <math.h>
  10. #include <bitset>
  11. #include <algorithm>
  12. #include <climits>
  13. using namespace std;
  14.  
  15. #define LS 2*i
  16. #define RS 2*i+1
  17. #define UP(i,x,y) for(i=x;i<=y;i++)
  18. #define DOWN(i,x,y) for(i=x;i>=y;i--)
  19. #define MEM(a,x) memset(a,x,sizeof(a))
  20. #define W(a) while(a)
  21. #define gcd(a,b) __gcd(a,b)
  22. #define LL long long
  23. #define N 1000005
  24. #define MOD 1000000007
  25. #define INF 0x3f3f3f3f
  26. #define EXP 1e-8
  27. int wa[N],wb[N],wsf[N],wv[N],sa[N];
  28. int rank1[N],height[N],s[N],a[N];
  29. //sa:字典序中排第i位的起始位置在str中第sa[i]
  30. //rank:就是str第i个位置的后缀是在字典序排第几
  31. //height:字典序排i和i-1的后缀的最长公共前缀
  32. int cmp(int *r,int a,int b,int k)
  33. {
  34. return r[a]==r[b]&&r[a+k]==r[b+k];
  35. }
  36. void getsa(int *r,int *sa,int n,int m)//n要包括末尾加入的0
  37. {
  38. int i,j,p,*x=wa,*y=wb,*t;
  39. for(i=0; i<m; i++) wsf[i]=0;
  40. for(i=0; i<n; i++) wsf[x[i]=r[i]]++;
  41. for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
  42. for(i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i;
  43. p=1;
  44. j=1;
  45. for(; p<n; j*=2,m=p)
  46. {
  47. for(p=0,i=n-j; i<n; i++) y[p++]=i;
  48. for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
  49. for(i=0; i<n; i++) wv[i]=x[y[i]];
  50. for(i=0; i<m; i++) wsf[i]=0;
  51. for(i=0; i<n; i++) wsf[wv[i]]++;
  52. for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
  53. for(i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
  54. t=x;
  55. x=y;
  56. y=t;
  57. x[sa[0]]=0;
  58. for(p=1,i=1; i<n; i++)
  59. x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
  60. }
  61. }
  62. void getheight(int *r,int n)//n不保存最后的0
  63. {
  64. int i,j,k=0;
  65. for(i=1; i<=n; i++) rank1[sa[i]]=i;
  66. for(i=0; i<n; i++)
  67. {
  68. if(k)
  69. k--;
  70. else
  71. k=0;
  72. j=sa[rank1[i]-1];
  73. while(r[i+k]==r[j+k])
  74. k++;
  75. height[rank1[i]]=k;
  76. }
  77. }
  78.  
  79. char str[N];
  80. int id[N];
  81. map<string,int> mat,ans;
  82. map<string,int>::iterator it;
  83.  
  84. int check(int x)//统计该状态包括几个串
  85. {
  86. int i,cnt = 0;
  87. for(i = 1; i<=10; i++)
  88. if((1<<i)&x)
  89. cnt++;
  90. return cnt;
  91. }
  92.  
  93. int main()
  94. {
  95. int n,i,j,k,len;
  96. while(~scanf("%d",&k))
  97. {
  98. MEM(id,0);
  99. n = 0;
  100. int p = 200;
  101. for(i = 1; i<=k; i++)
  102. {
  103. scanf("%s",str);
  104. len = strlen(str);
  105. for(j = 0; j<len; j++)
  106. {
  107. id[n] = i;
  108. s[n++] = str[j];
  109. }
  110. s[n++] = p++;
  111. for(j = len-1; j>=0; j--)
  112. s[n++] = str[j];
  113. s[n++] = p++;
  114. }
  115. if(k == 1)
  116. {
  117. printf("%s\n",str);
  118. continue;
  119. }
  120. getsa(s,sa,n,p);
  121. getheight(s,n);
  122. int l = 1,r = 1000;
  123. ans.clear();
  124. while(l<=r)
  125. {
  126. int mid = (l+r)/2;
  127. i = 0;
  128. mat.clear();
  129. while(i<n)
  130. {
  131. if(height[i]>=mid)
  132. {
  133. int tem = 1<<id[sa[i-1]];
  134. len = 2000;
  135. while(height[i]>=mid && i<n)//二进制记录串
  136. {
  137. tem |= (1<<id[sa[i]]);
  138. len = min(len,height[i]);
  139. i++;
  140. }
  141. if(tem!=1)
  142. {
  143. char s1[1005],s2[1005];
  144. for(j = len-1; j>=0; j--)
  145. {
  146. s1[len-1-j] = s[sa[i-1]+j];
  147. s2[j] = s[sa[i-1]+j];
  148. }
  149. s1[len] = s2[len] = '\0';
  150. if(mat.find(string(s1)) != mat.end())
  151. mat[string(s1)] |= tem;
  152. else
  153. mat[string(s2)] = tem;
  154. }
  155. }
  156. i++;
  157. }
  158. int flag = 0;
  159. for(it = mat.begin(); it!=mat.end(); it++)
  160. {
  161. if(check(it->second) >= k/2+1)
  162. {
  163. if(flag==0)
  164. {
  165. ans.clear();
  166. flag = 1;
  167. }
  168. ans.insert(*it);
  169. }
  170. }
  171. if(flag==0) r = mid-1;
  172. else l = mid+1;
  173. }
  174. if(ans.size()==0)
  175. printf("NONE\n");
  176. else
  177. {
  178. for(it = ans.begin(); it!=ans.end(); it++)
  179. {
  180. printf("%s\n",it->first.c_str());
  181. }
  182. }
  183. }
  184.  
  185. return 0;
  186. }

CSU1608: Particle Collider(后缀数组)的更多相关文章

  1. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  2. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  3. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  4. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  5. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  6. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

  7. 【UOJ #35】后缀排序 后缀数组模板

    http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...

  8. 【BZOJ-2119】股市的预测 后缀数组

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 334  Solved: 154[Submit][Status][Discuss ...

  9. 【BZOJ-4698】Sandy的卡片 后缀数组

    4698: Sdoi2008 Sandy的卡片 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 140  Solved: 55[Submit][Stat ...

随机推荐

  1. 数据库应用_innobackupex备份与恢复

    1.Percona软件介绍; 2.innobackupex的备份与恢复 一, Percona软件 在学习percona软件之前,我们看一下物理备份和mysqldump备份有哪些缺陷. 物理备份的缺点: ...

  2. c#获取DataTable某一列不重复的值,或者获取某一列的所有值

    实现该功能是用了DataView的筛选功能,DataView表示用于排序.筛选.搜索.编辑和导航的 DataTable 的可绑定数据的自定义视图. 这里做了一个简单易懂的Demo来讲述该方法. 1.建 ...

  3. 路飞学城Python-Day4(practise)

    #1.请用代码实现:利用下划线将列表的每一个元素拼接成字符串,li = ['alex','eric','rain']# li = ['alex','eric','rain']# print('_'.j ...

  4. 添加ArcGIS数据

    加载arcgis server的rest服务瓦片数据:ol.layer.Tile+ol.source.TileArcGISRest 加载arcgis online的在线瓦片数据:ol.layer.Ti ...

  5. POJ-1276 Cash Machine 多重背包 二进制优化

    题目链接:https://cn.vjudge.net/problem/POJ-1276 题意 懒得写了自己去看好了,困了赶紧写完这个回宿舍睡觉,明早还要考试. 思路 多重背包的二进制优化. 思路是将n ...

  6. 紫书 例题 10-3 UVa 10375 (唯一分解定理)

    这道题感觉非常的秀 因为结果会很大,所以就质因数分解分开来算 非常的巧妙! #include<cstdio> #include<vector> #include<cstr ...

  7. gdb与信号

    http://simohayha.iteye.com/blog/493091 gdb可以监测在你的程序中的任何信号. 主要靠的命令是: handle signal [keywords...] 这里的k ...

  8. Ubuntu搜狗输入法的安装

    Ubuntu搜狗输入法的安装 这个直接安装就可以了:因为现在的Ubuntu是16.04版本,输入法已经是Fcitx版本: 下载搜狗输入法For Linux之后,直接双击就可以安装了: 安装之后,需要注 ...

  9. iPhone4怎样鉴别翻新机

    加入杂志 步骤 1 2 3 4 5 6 由于iPhong4s的不给力,中国内地上市时间又尚未确定,造成近期iPhone4的价格涨了一大截,随之而来的就是大量的翻新机出现在市场上,那么 怎样判断自己手中 ...

  10. iOS_青花瓷Charles抓包

    使用青花瓷Charles抓取手机端的网络请求: 第一步,下载安装并打开Charles watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJlX2VtaW5l ...