标签:等价 about let i+1 mon dea ica text different
Time Limit: 4000MS | Memory Limit: 131072K | |
Total Submissions: 29277 | Accepted: 11887 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
Source
字符串的任何一个子串都是这个字符串的某个后缀的前缀。
求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大值。
两个字符串,考虑合并到一起,用一个没出现过的字符隔开
height中sa[i]和sa[i-1]不在同一个串里的最大值就是答案
这个值一定存在,因为排序后中两个串都有,至少存在一个分界一边是A一边是B
// // main.cpp // poj274 // // Created by Candy on 2016/12/27. // Copyright © 2016年 Candy. All rights reserved. // #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=2e5+5; int n,n1,n2,m,a[N]; char s[N]; int sa[N],c[N],t1[N],t2[N]; inline bool cmp(int *r,int a,int b,int j){ return a+j<=n&&b+j<=n&&r[a]==r[b]&&r[a+j]==r[b+j]; } int rnk[N],height[N]; void getHeight(int s[]){ int k=0; for(int i=1;i<=n;i++) rnk[sa[i]]=i; for(int i=1;i<=n;i++){ if(k) k--; if(rnk[i]==1) continue; int j=sa[rnk[i]-1]; while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++; height[rnk[i]]=k; } } void getSA(int s[]){ int *r=t1,*k=t2; for(int i=0;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[r[i]=s[i]]++; for(int i=1;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[r[i]]--]=i; for(int j=1;j<=n;j<<=1){ int p=0; for(int i=n-j+1;i<=n;i++) k[++p]=i; for(int i=1;i<=n;i++) if(sa[i]>j) k[++p]=sa[i]-j; for(int i=0;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[r[k[i]]]++; for(int i=1;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[r[k[i]]]--]=k[i]; swap(r,k);p=0;r[sa[1]]=++p; for(int i=2;i<=n;i++) r[sa[i]]=cmp(k,sa[i],sa[i-1],j)?p:++p; if(p>=n) break;m=p; } } void solve(){ int mx=0; for(int i=2;i<=n;i++){ if((sa[i]>n1&&sa[i-1]<n1)||(sa[i-1]>n1&&sa[i]<n1)) mx=max(mx,height[i]); } printf("%d",mx); } int main(){ scanf("%s",s+1); n1=strlen(s+1); for(int i=1;i<=n1;i++) a[i]=s[i]; a[++n1]=1; scanf("%s",s+1); n2=strlen(s+1); for(int i=1;i<=n2;i++) a[i+n1]=s[i]; n=n1+n2; //printf("%d %d %d\n",n1,n2,n); m=300; getSA(a); getHeight(a); solve(); return 0; }
POJ2774 Long Long Message [后缀数组]
标签:等价 about let i+1 mon dea ica text different
原文地址:http://www.cnblogs.com/candy99/p/6235145.html