2946: [Poi2000]公共串 后缀数组
2016-03-22 20:44
309 查看
后缀数组,我们可以二分答案,然后对height分组,然后判断一下有没有分别出现在各个串中的后缀。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 11000 #define inf 1000000007 using namespace std; int n,l,r,ans,len; int sa ,cc ,height ,rank ,t1 ,t2 ; int st[10]; char s ; bool q[10]; inline bool cmp(int *y,int a,int b,int k) { int arank1=y[a]; int brank1=y[b]; int arank2=a+k>=len?-1:y[a+k]; int brank2=b+k>=len?-1:y[b+k]; return arank1==brank1&&arank2==brank2; } inline void make_sa() { int *x=t1,*y=t2,m=256; for (int i=0;i<m;i++) cc[i]=0; for (int i=0;i<len;i++) ++cc[x[i]=s[i]]; for (int i=1;i<m;i++) cc[i]+=cc[i-1]; for (int i=len-1;~i;i--) sa[--cc[x[i]]]=i; for (int k=1;k<len;k<<=1) { int p=0; for (int i=len-k;i<len;i++) y[p++]=i; for (int i=0;i<len;i++) if (sa[i]>=k) y[p++]=sa[i]-k; for (int i=0;i<m;i++) cc[i]=0; for (int i=0;i<len;i++) ++cc[x[y[i]]]; for (int i=1;i<m;i++) cc[i]+=cc[i-1]; for (int i=len-1;~i;i--) sa[--cc[x[y[i]]]]=y[i]; swap(x,y); m=1; x[sa[0]]=0; for (int i=1;i<len;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],k)?m-1:m++; if (m>=len) break; } } inline void make_height() { for (int i=0;i<len;i++) rank[sa[i]]=i; int k=0; height[0]=0; for (int i=0;i<len;i++) { if (!rank[i]) continue; int j=sa[rank[i]-1]; if (k) k--; while (s[i+k]==s[j+k]) k++; height[rank[i]]=k; } } inline int find(int x) { if (s[x]=='&') return 0; for (int i=2;i<=n;i++) if (x<st[i]) return i-1; return n; } inline bool judge(int mid) { int now=1; while (now<len) { if (height[now]>=mid) { memset(q,false,sizeof(q)); q[find(sa[now-1])]=true; while (height[now]>=mid&&now<len) { q[find(sa[now])]=true; now++; } int flag=1; for (int i=1;i<=n;i++) if (!q[i]) { flag=0; break; } if (flag) return true; } else now++; } return false; } int main() { scanf("%d",&n); r=inf; for (int i=1;i<=n;i++) { scanf("%s",s+len); int tmp=strlen(s+len); len+=tmp; r=min(r,tmp); s[len]='&'; st[i+1]=len; len++; } make_sa(); make_height(); while (l<=r) { int mid=l+r>>1; if (judge(mid)) ans=mid,l=mid+1; else r=mid-1; } cout << ans << endl; return 0; }
相关文章推荐
- Blue Jeans (HDU_3080) KMP + 枚举
- Html+CSS hack技术介绍 以及常用hack
- Mysql 命令行快速导入数据
- Latex中制作表格
- HDU3613 Best Reward 3连发之KMP
- 开发ionic准备之安卓模拟器设置(2)
- Character 比较注意先要转换成字符串类型
- java产生4位随机数
- jQuery学习 day01
- ping 超时原因
- mysql 删除前几天记录
- leetcode : 327. Count of Range Sum : 连续和在指定区间内
- 使用IDEA进行代码托管
- pt-query-digest查询日志分析工具
- Android SwipeRefreshLayout实现下拉刷新,上拉加载、滑动加载(自动加载)和点击加载
- Carthage
- 顺序表与单链表的比较
- Bloom Filter概念和原理
- java 对xml文件进行 增删改查
- java指导