2946: [Poi2000]公共串 后缀数组
来源:互联网 发布:程序员平均年龄 编辑:程序博客网 时间:2024/05/03 13:47
后缀数组,我们可以二分答案,然后对
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define N 11000#define inf 1000000007using namespace std;int n,l,r,ans,len;int sa[N],cc[N],height[N],rank[N],t1[N],t2[N];int st[10];char s[N];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;}
0 0
- BZOJ 2946 [Poi2000]公共串 后缀数组
- 2946: [Poi2000]公共串|哈希|后缀数组
- 2946: [Poi2000]公共串 后缀数组
- 【BZOJ 2946】[Poi2000]公共串 后缀数组
- BZOJ 2946: [Poi2000]公共串 后缀数组
- [bzoj2946][后缀数组][Poi2000]公共串
- BZOJ 2946 Poi2000 公共串 后缀自动机
- 2946: [Poi2000]公共串 后缀自动机
- bzoj 2946: [Poi2000]公共串 后缀自动机
- BZOJ 2946 [Poi2000]公共串 后缀自动机
- bzoj 2946: [Poi2000]公共串 (后缀自动机)
- 后缀自动机 模板 【Poi2000】 公共串 bzoj 2946
- [BZOJ2946][Poi2000]公共串 && 后缀自动机
- 【bzoj2946】[Poi2000]公共串 后缀自动机
- bzoj2946 [Poi2000]公共串 后缀自动机
- bzoj 2946: [Poi2000]公共串
- BZOJ 2946 [Poi2000]公共串
- [后缀自动机 模板题] SPOJ 1812Longest Common Substring II & BZOJ 2946 [Poi2000]公共串
- Makefile原理
- Mysql 命令行快速导入数据
- 黑马程序员——Java学习日志之Set集合
- 南阳题目57-6174问题
- c++算法之分解质因数
- 2946: [Poi2000]公共串 后缀数组
- 204. Count Primes
- 蛇形填数的递归实现
- iOS中单例的通用写法
- Java基础学习第二十一天——递归与字节流
- RHCE7.0-搭建基于NFS网络文件系统服务
- [POJ 2195]Going Home[费用流]
- HDU 3065 病毒侵袭持续中(AC自动机)
- HDU 4763 数据结构之KMP+二分