HDU1403 Longest Common Substring 后缀数组

Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=1403

 

前不久在HDU上做了个友谊赛,结果惨不忍睹。

 

这道题当时是不知道得用后缀数组做的,做了n久还是TLE。

 

后来查了一下,然后又问了一下,发现确实是后缀数组。然后花了几天时间来学习= =

 

弱弱地贴下别人的代码,目前还没完全吃透……

 

#include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> using namespace std; #define maxn 200100 char s[maxn]; int len1; int word[maxn]; int h2,but[maxn]; int *sa1,*sa2,*rank,*rank2; int mem[4][maxn],height[maxn]; void createsuffixarray(int* sztext,int l,int m) { int i,h; sa1=mem[0]; sa2=mem[1]; rank=mem[2]; rank2=mem[3]; for(i=0;i<l;i++) but[sztext[i]]++; for(i=1;i<m;i++) but[i]+=but[i-1]; for(i=l-1;i>=0;i--) sa1[--but[sztext[i]]]=i; for(rank[sa1[0]]=0,i=1;i<l;i++) { if(sztext[sa1[i]]==sztext[sa1[i-1]]) rank[sa1[i]]=rank[sa1[i-1]]; else rank[sa1[i]]=rank[sa1[i-1]]+1; } for(h=1;h<l&&rank[sa1[l-1]]<l-1;h*=2) { for(i=0;i<l;i++) but[rank[sa1[i]]]=i; for(i=l-1;i>=0;i--) if(h<=sa1[i]) sa2[but[rank[sa1[i]-h]]--]=sa1[i]-h; for(i=l-h,h2=l-(h>>1);i<h2;i++) sa2[but[rank[i]]]=i; for(rank2[sa2[0]],i=1;i<l;i++) { if(rank[sa2[i]]!=rank[sa2[i-1]]||rank[sa2[i]+h]!=rank[sa2[i-1]+h]) rank2[sa2[i]]=rank2[sa2[i-1]]+1; else rank2[sa2[i]]=rank2[sa2[i-1]]; } swap(sa1,sa2); swap(rank,rank2); } } void calheight(int* sztext,int l) { int i, j, k; for(i=0,k=0;i<l;i++) { if(rank[i]==l-1) height[rank[i]]=k=0; else { if(k>0) k--; j=sa1[rank[i]+1]; for(;sztext[i+k]==sztext[j+k];k++); height[rank[i]]=k; } } } void init() { memset(height,0,sizeof(height)); memset(but,0,sizeof(but)); memset(mem,0,sizeof(mem)); } int main() { int i; while(scanf("%s",s)!=EOF) { init(); len1=strlen(s); s[len1++]='z'+1; scanf("%s",s+len1); int n=strlen(s); for(i=0;i<n;i++) { word[i]=s[i]-'a'+1; } word[n++]=0; createsuffixarray(word,n,256); calheight(word,n); int ans=0; len1--; for (i=0;i<n-1;i++) { if ((sa1[i]-len1)*(sa1[i+1]-len1)<0&&height[i]>ans) ans=height[i]; } printf("%d/n",ans); } return 0; }

 

是哪位帅哥的,小弟在此膜拜一下。

 

刚开始还是桶排序没怎么看明白,而且无数的下标中的下标,搞的头晕目眩的。

 

后缀数组还有很多的应用,还得慢慢学习。

你可能感兴趣的:(ini)