CSU1608: Particle Collider(后缀数组)
来源:互联网 发布:java注释规范 编辑:程序博客网 时间:2024/05/20 10:14
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
3ABCABDBCD3AAABBBCCC2ABCDBA
Sample Output
ABBCNONEAB
HINT
Source
#include <iostream>#include <stdio.h>#include <string.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <math.h>#include <bitset>#include <algorithm>#include <climits>using namespace std;#define LS 2*i#define RS 2*i+1#define UP(i,x,y) for(i=x;i<=y;i++)#define DOWN(i,x,y) for(i=x;i>=y;i--)#define MEM(a,x) memset(a,x,sizeof(a))#define W(a) while(a)#define gcd(a,b) __gcd(a,b)#define LL long long#define N 1000005#define MOD 1000000007#define INF 0x3f3f3f3f#define EXP 1e-8int wa[N],wb[N],wsf[N],wv[N],sa[N];int rank1[N],height[N],s[N],a[N];//sa:字典序中排第i位的起始位置在str中第sa[i]//rank:就是str第i个位置的后缀是在字典序排第几//height:字典序排i和i-1的后缀的最长公共前缀int cmp(int *r,int a,int b,int k){ return r[a]==r[b]&&r[a+k]==r[b+k];}void getsa(int *r,int *sa,int n,int m)//n要包含末尾添加的0{ int i,j,p,*x=wa,*y=wb,*t; for(i=0; i<m; i++) wsf[i]=0; for(i=0; i<n; i++) wsf[x[i]=r[i]]++; for(i=1; i<m; i++) wsf[i]+=wsf[i-1]; for(i=n-1; i>=0; i--) sa[--wsf[x[i]]]=i; p=1; j=1; for(; p<n; j*=2,m=p) { for(p=0,i=n-j; i<n; i++) y[p++]=i; for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0; i<n; i++) wv[i]=x[y[i]]; for(i=0; i<m; i++) wsf[i]=0; for(i=0; i<n; i++) wsf[wv[i]]++; for(i=1; i<m; i++) wsf[i]+=wsf[i-1]; for(i=n-1; i>=0; i--) sa[--wsf[wv[i]]]=y[i]; t=x; x=y; y=t; x[sa[0]]=0; for(p=1,i=1; i<n; i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++; }}void getheight(int *r,int n)//n不保存最后的0{ int i,j,k=0; for(i=1; i<=n; i++) rank1[sa[i]]=i; for(i=0; i<n; i++) { if(k) k--; else k=0; j=sa[rank1[i]-1]; while(r[i+k]==r[j+k]) k++; height[rank1[i]]=k; }}char str[N];int id[N];map<string,int> mat,ans;map<string,int>::iterator it;int check(int x)//统计该状态包括几个串{ int i,cnt = 0; for(i = 1; i<=10; i++) if((1<<i)&x) cnt++; return cnt;}int main(){ int n,i,j,k,len; while(~scanf("%d",&k)) { MEM(id,0); n = 0; int p = 200; for(i = 1; i<=k; i++) { scanf("%s",str); len = strlen(str); for(j = 0; j<len; j++) { id[n] = i; s[n++] = str[j]; } s[n++] = p++; for(j = len-1; j>=0; j--) s[n++] = str[j]; s[n++] = p++; } if(k == 1) { printf("%s\n",str); continue; } getsa(s,sa,n,p); getheight(s,n); int l = 1,r = 1000; ans.clear(); while(l<=r) { int mid = (l+r)/2; i = 0; mat.clear(); while(i<n) { if(height[i]>=mid) { int tem = 1<<id[sa[i-1]]; len = 2000; while(height[i]>=mid && i<n)//二进制记录串 { tem |= (1<<id[sa[i]]); len = min(len,height[i]); i++; } if(tem!=1) { char s1[1005],s2[1005]; for(j = len-1; j>=0; j--) { s1[len-1-j] = s[sa[i-1]+j]; s2[j] = s[sa[i-1]+j]; } s1[len] = s2[len] = '\0'; if(mat.find(string(s1)) != mat.end()) mat[string(s1)] |= tem; else mat[string(s2)] = tem; } } i++; } int flag = 0; for(it = mat.begin(); it!=mat.end(); it++) { if(check(it->second) >= k/2+1) { if(flag==0) { ans.clear(); flag = 1; } ans.insert(*it); } } if(flag==0) r = mid-1; else l = mid+1; } if(ans.size()==0) printf("NONE\n"); else { for(it = ans.begin(); it!=ans.end(); it++) { printf("%s\n",it->first.c_str()); } } } return 0;}
- CSU1608: Particle Collider(后缀数组)
- CSU 1608 Particle Collider(二分+后缀数组)
- CSU 1608 Particle Collider(后缀数组+二分)
- 后缀树/后缀数组
- 后缀树 后缀数组
- 【后缀数组】后缀排序
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- Eclipse更改项目包名
- QuartzCode,将iOS / MacOS 开发中使用的基础动画转换为Object-C / Swift代码
- string 和StringBuffer StringBuilder的区别
- Erlang的常驻模块与功能模块
- SAP审计
- CSU1608: Particle Collider(后缀数组)
- Extjs4 grid动态获取列的实现
- 教你做GRE的新旧观点型阅读
- 渣渣ACM日记——1013-Digital Roots (HDOJ)
- Lightoj 1009. K-based Numbers(DP)
- hihoCoder#1037 : 数字三角形(DP)
- 要用心去感受这个世界
- 工厂模式
- EXT 隐藏TBAR