题目大意:
计算两个字符串的最长的公共字符串字串的长度。
思路分析:
将两个串合并起来。
然后直接跑后缀数组求出height
然后就可以直接扫描一次height ,加个是不是在一个串中的判断就可以了。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 200005 using namespace std; char str[maxn]; int sa[maxn],t1[maxn],t2[maxn],c[maxn],n; void suffix(int m) { int *x=t1,*y=t2; for(int i=0;i<m;i++)c[i]=0; for(int i=0;i<n;i++)c[x[i]=str[i]]++; for(int i=1;i<m;i++)c[i]+=c[i-1]; for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i; for(int k=1;k<=n;k<<=1) { int p=0; for(int i=n-k;i<n;i++)y[p++]=i; for(int i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k; for(int i=0;i<m;i++)c[i]=0; for(int i=0;i<n;i++)c[x[y[i]]]++; for(int i=0;i<m;i++)c[i]+=c[i-1]; for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(int i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; if(p>=n)break; m=p; } } int rank[maxn],height[maxn]; void getheight() { int k=0; for(int i=0;i<n;i++)rank[sa[i]]=i; for(int i=0;i<n;i++) { if(k)k--; if(!rank[i])continue; int j=sa[rank[i]-1]; while(str[i+k]==str[j+k])k++; height[rank[i]]=k; } } bool ok(int len) { int down,up; down=up=sa[0]; for(int i=1;i<n;i++) { if(height[i]<len) { down=up=sa[i]; } else { down=min(sa[i],down); up=max(sa[i],up); } if(up-down>len)return true; } return false; } int bin() { int l=4,r=n,ans=0; while(l<=r) { int mid=(l+r)>>1; if(ok(mid)) { ans=mid,l=mid+1; } else r=mid-1; } return ans; } char tmp[11111]; int main() { int T; scanf("%d",&T); getchar(); while(T--) { gets(tmp); int len=strlen(tmp); int top=0; for(int i=0;i<=len;i++) str[top++]=tmp[i]; gets(tmp); int cnt=0; while(tmp[cnt]!='\0')str[top++]=tmp[cnt++]; n=top; suffix(256); getheight(); int ans=0; for(int i=1;i<n;i++) { if((sa[i-1]<len)!=(sa[i]<len)) ans=max(ans,height[i]); } printf("Nejdelsi spolecny retezec ma delku %d.\n",ans); } return 0; } /* 10 1 2 3 4 5 6 7 8 9 10 */
POJ 2217 Secretary (后缀数组),布布扣,bubuko.com
时间: 2024-10-25 23:10:36