POJ 2774 Long Long Message

来源:互联网 发布:javaweb邮件系统源码 编辑:程序博客网 时间:2024/06/01 13:23

大概就是后缀数组的模板题(看着0下标好累,统统改成了1下标233)

两个串中间加一个从未出现的字符分割以免连在一起形成了更大的height,然后就是对于每一个后缀查找height,若它之前的那个后缀和它不在同一个串中(sa一个大于len1,一个小于len1)即为合法情况。扫一遍就ok了。


#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<algorithm>using namespace std;const int maxn=100005;int n,m;int c[maxn<<1];int s[maxn<<1];char ss[maxn<<1];int sa[maxn<<1],rank[maxn<<1],height[maxn<<1];int tmp[maxn<<1],temp[maxn<<1];void getsa(){int *x=tmp,*y=temp,cnt;int m=30;for(int i=1;i<=m;i++)c[i]=0;for(int i=1;i<=n;i++)c[x[i]=s[i]]++;for(int i=2;i<=m;i++)c[i]+=c[i-1];for(int i=n;i>=1;i--)sa[c[x[i]]--]=i;for(int k=1;k<=n;k<<=1){cnt=0;for(int i=n-k+1;i<=n;i++)y[++cnt]=i;for(int i=1;i<=n;i++)if(sa[i]>k)y[++cnt]=sa[i]-k;for(int i=1;i<=m;i++)c[i]=0;for(int i=1;i<=n;i++)c[x[y[i]]]++;for(int i=2;i<=m;i++)c[i]+=c[i-1];for(int i=n;i>=1;i--)sa[c[x[y[i]]]--]=y[i];swap(x,y);x[sa[1]]=cnt=1;for(int i=2;i<=n;i++)x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?cnt:++cnt;if(cnt>=n)break;m=cnt;}cnt=0;for(int i=1;i<=n;i++)rank[sa[i]]=i;for(int i=1;i<=n;i++){if(cnt)cnt--;int j=sa[rank[i]-1];while(s[i+cnt]==s[j+cnt])cnt++;height[rank[i]]=cnt;}}int main(){scanf("%s",ss+1);int len1=strlen(ss+1);for(int i=1;i<=len1;i++)s[i]=ss[i]-'a'+2;s[len1+1]=1;scanf("%s",ss+1);int len2=strlen(ss+1);for(int i=1;i<=len2;i++)s[len1+i+1]=ss[i]-'a'+2;n=len1+len2+1;getsa();int ans=0;for(int i=1;i<=n;i++){if(height[i]>ans&&((sa[i]>=len1&&sa[i-1]<len1)||(sa[i]<len1&&sa[i-1]>=len1)))ans=height[i];}printf("%d",ans);}


原创粉丝点击