SPOJ 220 . Relevant Phrases of Annihilation(后缀数组)
来源:互联网 发布:linux telnet root登录 编辑:程序博客网 时间:2024/04/28 10:59
SPOJ 220 . Relevant Phrases of Annihilation(后缀数组)
题意:
给你N个串,要你在这N个串中找出这样一个最长的子串长度.该串在任意一个串中至少出现了2次,并且不重叠的.
分析:
罗穗骞《后缀数组——处理字符串的有力工具》例题.
首先依然连接所有串,并且加上分隔符.然后依然是二分答案,看看长为limit的这个串是否存在.在每个height组内看看是否覆盖了所有串两次且最小位置与最大位置之差>=limit.
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100000+1000;int who[maxn];//who[i]表示后缀i属于原始第几个串,如果为0则是人为添加的字符int num;//原始串的个数int min_pos[15],max_pos[15];struct SuffixArray{ int s[maxn]; int sa[maxn],rank[maxn],height[maxn]; int t1[maxn],t2[maxn],c[maxn],n; void build_sa(int m) { int i,*x=t1,*y=t2; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[i]=s[i]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; for(i=n-k;i<n;i++) y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=k) y[p++]=sa[i]-k; for(i=0;i<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1,x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++; if(p>=n) break; m=p; } } void build_height() { int i,j,k=0; for(i=0;i<n;i++) rank[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rank[i]-1]; while(s[i+k]==s[j+k])k++; height[rank[i]]=k; } } bool check(int limit) { int i,j,k; for(i=2;i<n;i=j+1) { for(;height[i]<limit&&i<n;i++);//i-1是该组下界 for(j=i;height[j]>=limit&&j<n;j++);//j-1是该组上界 if(j-i+1<num) continue; for(k=1;k<=num;k++){min_pos[k]=10001;max_pos[k]=-1;} for(k=i-1;k<j;k++) { if(sa[k]<min_pos[who[sa[k]]]) min_pos[who[sa[k]]]=sa[k]; if(sa[k]>max_pos[who[sa[k]]]) max_pos[who[sa[k]]]=sa[k]; } for(k=1;k<=num;k++)if(max_pos[k]-min_pos[k]<limit)break; if(k>num) return true; } return false; } void solve() { int min=1,max=5000; while(min<=max) { int mid=min+(max-min)/2; if(check(mid))min=mid+1; else max=mid-1; } printf("%d\n",max); }}sa;int main(){ char str[10000+100]; int n,T; scanf("%d",&T); while(T--) { scanf("%d",&n); sa.n=0; num=n; for(int i=1;i<=n;i++) { scanf("%s",str); int len=strlen(str); for(int j=0;j<len;j++) { sa.s[sa.n+j]=str[j]+100; who[sa.n+j]=i;//归属第几个串 } sa.s[sa.n+len]=i;//分割符 who[sa.n+len]=0;//分割符归属0 sa.n=sa.n+len+1;//串长增加 } sa.s[sa.n-1]=0; sa.build_sa(228); sa.build_height(); sa.solve(); }}
0 0
- SPOJ 220 PHRASES Relevant Phrases of Annihilation 后缀数组
- spoj 220 PHRASES - Relevant Phrases of Annihilation(后缀数组)
- SPOJ 220 . Relevant Phrases of Annihilation(后缀数组)
- SPOJ 220 Relevant Phrases of Annihilation (后缀数组)
- 【后缀数组】【spoj 220】Relevant Phrases of Annihilation
- spoj 220 Relevant Phrases of Annihilation (后缀数组应用)
- SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分)
- Relevant Phrases of Annihilation SPOJ (后缀数组)
- 字符串练习题:SPOJ 220 Relevant Phrases of Annihilation(后缀数组加二分)
- SPOJ220:Relevant Phrases of Annihilation(后缀数组)
- SPOJ-220-Relevant Phrases of Annihilation
- Relevant Phrases of Annihilation SPOJ
- Relevant Phrases of Annihilation SPOJ
- spoj Relevant Phrases of Annihilation
- [SPOJ220]PHRASES - Relevant Phrases of Annihilation(后缀数组+二分)
- SPOJ PHRASES Relevant Phrases of Annihilation
- SPOJ PHRASES Relevant Phrases of Annihilation
- spoj 220 Relevant Phrases of Annihilation (后缀数组 每个串中都至少出现两次的不重叠最长子串)
- ibatis动态查询条件
- Objective-C ,ios,iphone开发基础:JSON解析(使用苹果官方提供的JSON库:NSJSONSerialization)
- GEM5简介
- 回车与换行的区别
- 权力游戏“紫婚”毁誉参半 童话镇入佳境
- SPOJ 220 . Relevant Phrases of Annihilation(后缀数组)
- HttpURLConnection和HttpClient获取Json数据
- UVA The Mad Numerologist
- TI DSP库VLIB介绍
- ViewPager3D
- java的事件监听
- c++ 第二章 类的成员变量、函数
- Android开发之得到新打开Activity关闭后返回的数据
- 计算N级行列式