poj 2774
后缀数组
代码:
#include<iostream> #include<fstream> using namespace std; int sa[200003],sa1[200003],rank1[200003]; int rank[200003],y[200003],h[200003]; int pow=1; char m[200004]; int c[200003]; int cmp2(const void *a,const void *b){ int x=*(int*)a; int y=*(int*)b; if(rank[x]!=rank[y]) return(rank[x]-rank[y]); else return(rank[x+pow]-rank[y+pow]); } void creat(int n){ int i,j,t; for(i=0;i<=256;i++) c[i]=0; for(i=0;i<n;i++) c[m[i]]++; for(i=1;i<=256;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[m[i]]]=i; for(i=0,j=0;i<n;i++) { if(i>0&&m[sa[i]]!=m[sa[i-1]]) j++; rank[sa[i]]=j; } for(pow=1;pow<n;pow*=2) { for(i=0;i<n;i++) c[i]=0; for(i=0;i<n;i++) if(sa[i]+pow<n) c[rank[sa[i]+pow]]++; else c[rank[sa[i]]]++; for(i=1;i<n;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) if(sa[i]+pow<n) sa1[--c[rank[sa[i]+pow]]]=sa[i]; else sa1[--c[rank[sa[i]]]]=sa[i]; for(i=0;i<n;i++) c[i]=0; for(i=0;i<n;i++) c[rank[sa1[i]]]++; for(i=1;i<n;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[rank[sa1[i]]]]=sa1[i]; j=0; for(i=0;i<n;i++) { if(i>0&&cmp2(&sa[i],&sa[i-1])!=0) j++; rank1[sa[i]]=j; } for(i=0;i<n;i++) rank[i]=rank1[i]; } } void height(int n){ int i,j,k=0; for(i=0;i<n;i++) { if(rank[i]==0) h[rank[i]]=k=0; else { if(k>0) k--; j=sa[rank[i]-1]; for(;m[i+k]==m[j+k];k++); h[rank[i]]=k; } } } int judge(int s,int t){ if(sa[s]<t&&sa[s-1]<t) return(0); if(sa[s]>t&&sa[s-1]>t) return(0); return(1); } int main(){ //ifstream cin("in.txt"); int i,j,k,t; cin>>m; //scanf("%s",m); k=strlen(m); t=k; m[k]=2; cin>>m+k+1; //scanf("%s",m+k+1); k=strlen(m); m[k]=1; k++; creat(k); height(k); j=0; for(i=1;i<k;i++) if(j<h[i]&&judge(i,t)) j=h[i]; cout<<j<<endl; return(0); }